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.in41
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-dsfromkey.855
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-dsfromkey.c314
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-dsfromkey.docbook78
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-dsfromkey.html67
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.886
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c336
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook195
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html136
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.8114
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.c768
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.docbook264
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.html196
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-revoke.883
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-revoke.c269
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-revoke.docbook149
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-revoke.html87
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-settime.8166
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-settime.c576
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-settime.docbook319
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-settime.html208
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.8154
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.c1157
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.docbook246
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.html200
-rw-r--r--contrib/bind9/bin/dnssec/dnssectool.c223
-rw-r--r--contrib/bind9/bin/dnssec/dnssectool.h33
27 files changed, 5456 insertions, 1064 deletions
diff --git a/contrib/bind9/bin/dnssec/Makefile.in b/contrib/bind9/bin/dnssec/Makefile.in
index 50429be..0f5e4e8 100644
--- a/contrib/bind9/bin/dnssec/Makefile.in
+++ b/contrib/bind9/bin/dnssec/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -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.35 2008-11-07 02:28:49 marka Exp $
+# $Id: Makefile.in,v 1.42 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -25,11 +25,12 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES}
-CDEFINES = -DVERSION=\"${VERSION}\"
+CDEFINES = -DVERSION=\"${VERSION}\" @USE_PKCS11@
CWARNINGS =
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
@@ -38,44 +39,56 @@ DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${DNSLIBS} ${ISCNOSYMLIBS} @LIBS@
+
# Alphabetically
TARGETS = dnssec-keygen@EXEEXT@ dnssec-signzone@EXEEXT@ \
- dnssec-keyfromlabel@EXEEXT@ dnssec-dsfromkey@EXEEXT@
+ dnssec-keyfromlabel@EXEEXT@ dnssec-dsfromkey@EXEEXT@ \
+ dnssec-revoke@EXEEXT@ dnssec-settime@EXEEXT@
OBJS = dnssectool.@O@
SRCS = dnssec-dsfromkey.c dnssec-keyfromlabel.c dnssec-keygen.c \
- dnssec-signzone.c dnssectool.c
+ dnssec-revoke.c dnssec-settime.c dnssec-signzone.c dnssectool.c
MANPAGES = dnssec-dsfromkey.8 dnssec-keyfromlabel.8 dnssec-keygen.8 \
- dnssec-signzone.8
+ dnssec-revoke.8 dnssec-settime.8 dnssec-signzone.8
HTMLPAGES = dnssec-dsfromkey.html dnssec-keyfromlabel.html \
- dnssec-keygen.html dnssec-signzone.html
+ dnssec-keygen.html dnssec-revoke.html \
+ dnssec-settime.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}
+ export BASEOBJS="dnssec-dsfromkey.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
dnssec-keyfromlabel@EXEEXT@: dnssec-keyfromlabel.@O@ ${OBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dnssec-keyfromlabel.@O@ ${OBJS} ${LIBS}
+ export BASEOBJS="dnssec-keyfromlabel.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
dnssec-keygen@EXEEXT@: dnssec-keygen.@O@ ${OBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dnssec-keygen.@O@ ${OBJS} ${LIBS}
+ export BASEOBJS="dnssec-keygen.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
dnssec-signzone.@O@: dnssec-signzone.c
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \
-c ${srcdir}/dnssec-signzone.c
dnssec-signzone@EXEEXT@: dnssec-signzone.@O@ ${OBJS} ${DEPLIBS}
+ export BASEOBJS="dnssec-signzone.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
+
+dnssec-revoke@EXEEXT@: dnssec-revoke.@O@ ${OBJS} ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ dnssec-revoke.@O@ ${OBJS} ${LIBS}
+
+dnssec-settime@EXEEXT@: dnssec-settime.@O@ ${OBJS} ${DEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dnssec-signzone.@O@ ${OBJS} ${LIBS}
+ dnssec-settime.@O@ ${OBJS} ${LIBS}
doc man:: ${MANOBJS}
diff --git a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.8 b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.8
index c49ccdc..25aa2bf 100644
--- a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.8
+++ b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.8
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2008-2010 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
@@ -12,18 +12,18 @@
.\" 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.14.1 2010-05-19 02:06:11 tbox Exp $
+.\" $Id: dnssec-dsfromkey.8,v 1.13 2010-12-24 01:14:20 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
+.\" Date: August 26, 2009
.\" Manual: BIND9
.\" Source: BIND9
.\"
-.TH "DNSSEC\-DSFROMKEY" "8" "November 29, 2008" "BIND9" "BIND9"
+.TH "DNSSEC\-DSFROMKEY" "8" "August 26, 2009" "BIND9" "BIND9"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -32,9 +32,9 @@
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}
+\fBdnssec\-dsfromkey\fR [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-l\ \fR\fB\fIdomain\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}
+\fBdnssec\-dsfromkey\fR {\-s} [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-s\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIfile\fR\fR] [\fB\-A\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {dnsname}
.SH "DESCRIPTION"
.PP
\fBdnssec\-dsfromkey\fR
@@ -55,31 +55,49 @@ Use SHA\-256 as the digest algorithm.
.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.
+must be one of SHA\-1 (SHA1), SHA\-256 (SHA256) or GOST. These values are case insensitive.
.RE
.PP
-\-v \fIlevel\fR
+\-K \fIdirectory\fR
.RS 4
-Sets the debugging level.
+Look for key files (or, in keyset mode,
+\fIkeyset\-\fR
+files) in
+\fBdirectory\fR.
+.RE
+.PP
+\-f \fIfile\fR
+.RS 4
+Zone file mode: in place of the keyfile name, the argument is the DNS domain name of a zone master file, which can be read from
+\fBfile\fR. If the zone name is the same as
+\fBfile\fR, then it may be omitted.
+.RE
+.PP
+\-A
+.RS 4
+Include ZSK's when generating DS records. Without this option, only keys which have the KSK flag set will be converted to DS records and printed. Useful only in zone file mode.
+.RE
+.PP
+\-l \fIdomain\fR
+.RS 4
+Generate a DLV set instead of a DS set. The specified
+\fBdomain\fR
+is appended to the name for each record in the set. The DNSSEC Lookaside Validation (DLV) RR is described in RFC 4431.
.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.
+Keyset mode: in place of the keyfile name, the argument is the DNS domain name of a keyset file.
.RE
.PP
\-c \fIclass\fR
.RS 4
-Specifies the DNS class (default is IN), useful only in the keyset mode.
+Specifies the DNS class (default is IN). Useful only in keyset or zone file mode.
.RE
.PP
-\-d \fIdirectory\fR
+\-v \fIlevel\fR
.RS 4
-Look for
-\fIkeyset\fR
-files in
-\fBdirectory\fR
-as the directory, ignored when not in the keyset mode.
+Sets the debugging level.
.RE
.SH "EXAMPLE"
.PP
@@ -115,10 +133,11 @@ A keyfile error can give a "file not found" even if the file exists.
\fBdnssec\-signzone\fR(8),
BIND 9 Administrator Reference Manual,
RFC 3658,
+RFC 4431.
RFC 4509.
.SH "AUTHOR"
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2008 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2008\-2010 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c
index 934d25b..b7f84a0 100644
--- a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c
+++ b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-dsfromkey.c,v 1.2.14.6 2010-01-11 23:47:22 tbox Exp $ */
+/* $Id: dnssec-dsfromkey.c,v 1.19 2010-12-23 04:07:59 marka Exp $ */
/*! \file */
@@ -36,6 +36,8 @@
#include <dns/ds.h>
#include <dns/fixedname.h>
#include <dns/log.h>
+#include <dns/keyvalues.h>
+#include <dns/master.h>
#include <dns/name.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
@@ -48,54 +50,40 @@
#include "dnssectool.h"
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* AIX, WIN32, and others don't define this. */
+#endif
+
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 dns_fixedname_t fixed;
+static dns_name_t *name = NULL;
+static isc_mem_t *mctx = NULL;
-static void
-loadkeys(char *dirname, char *setname)
-{
- isc_result_t result;
- char filename[1024];
- isc_buffer_t buf;
+static isc_result_t
+initname(char *setname) {
+ isc_result_t result;
+ 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);
+ result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
+ return (result);
+}
- isc_buffer_init(&buf, filename, sizeof(filename));
- if (dirname != NULL) {
- if (isc_buffer_availablelength(&buf) < strlen(dirname))
- fatal("directory name '%s' too long", dirname);
- isc_buffer_putstr(&buf, dirname);
- if (dirname[strlen(dirname) - 1] != '/') {
- if (isc_buffer_availablelength(&buf) < 1)
- fatal("directory name '%s' too long", dirname);
- isc_buffer_putstr(&buf, "/");
- }
- }
+static isc_result_t
+loadsetfromfile(char *filename, dns_rdataset_t *rdataset) {
+ isc_result_t result;
+ dns_db_t *db = NULL;
+ dns_dbnode_t *node = NULL;
+ char setname[DNS_NAME_FORMATSIZE];
- if (isc_buffer_availablelength(&buf) < strlen("keyset-"))
- fatal("directory name '%s' too long", dirname);
- 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);
+ dns_name_format(name, setname, sizeof(setname));
result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
rdclass, 0, NULL, &db);
@@ -111,11 +99,49 @@ loadkeys(char *dirname, char *setname)
fatal("can't find %s node in %s", setname, filename);
result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey,
- 0, 0, &keyset, NULL);
+ 0, 0, rdataset, 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");
+
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ if (db != NULL)
+ dns_db_detach(&db);
+ return (result);
+}
+
+static isc_result_t
+loadkeyset(char *dirname, dns_rdataset_t *rdataset) {
+ isc_result_t result;
+ char filename[PATH_MAX + 1];
+ isc_buffer_t buf;
+
+ dns_rdataset_init(rdataset);
+
+ isc_buffer_init(&buf, filename, sizeof(filename));
+ if (dirname != NULL) {
+ /* allow room for a trailing slash */
+ if (strlen(dirname) >= isc_buffer_availablelength(&buf))
+ return (ISC_R_NOSPACE);
+ isc_buffer_putstr(&buf, dirname);
+ if (dirname[strlen(dirname) - 1] != '/')
+ isc_buffer_putstr(&buf, "/");
+ }
+
+ if (isc_buffer_availablelength(&buf) < 7)
+ return (ISC_R_NOSPACE);
+ 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)
+ return (ISC_R_NOSPACE);
+ isc_buffer_putuint8(&buf, 0);
+
+ return (loadsetfromfile(filename, rdataset));
}
static void
@@ -127,20 +153,20 @@ loadkey(char *filename, unsigned char *key_buf, unsigned int key_buf_size,
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);
+ result = dst_key_fromnamedfile(filename, NULL, 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];
+ char keystr[DST_KEY_FORMATSIZE];
- key_format(key, keystr, sizeof(keystr));
+ dst_key_format(key, keystr, sizeof(keystr));
fprintf(stderr, "%s: %s\n", program, keystr);
}
@@ -169,7 +195,7 @@ logkey(dns_rdata_t *rdata)
isc_result_t result;
dst_key_t *key = NULL;
isc_buffer_t buf;
- char keystr[KEY_FORMATSIZE];
+ char keystr[DST_KEY_FORMATSIZE];
isc_buffer_init(&buf, rdata->data, rdata->length);
isc_buffer_add(&buf, rdata->length);
@@ -177,89 +203,132 @@ logkey(dns_rdata_t *rdata)
if (result != ISC_R_SUCCESS)
return;
- key_format(key, keystr, sizeof(keystr));
+ dst_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)
+emit(unsigned int dtype, isc_boolean_t showall, char *lookaside,
+ 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_result_t result;
+ unsigned char buf[DNS_DS_BUFFERSIZE];
+ char text_buf[DST_KEY_MAXTEXTSIZE];
+ char name_buf[DNS_NAME_MAXWIRE];
+ char class_buf[10];
+ isc_buffer_t textb, nameb, classb;
+ isc_region_t r;
+ dns_rdata_t ds;
+ dns_rdata_dnskey_t dnskey;
isc_buffer_init(&textb, text_buf, sizeof(text_buf));
+ isc_buffer_init(&nameb, name_buf, sizeof(name_buf));
isc_buffer_init(&classb, class_buf, sizeof(class_buf));
dns_rdata_init(&ds);
+ result = dns_rdata_tostruct(rdata, &dnskey, NULL);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't convert DNSKEY");
+
+ if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 && !showall)
+ return;
+
result = dns_ds_buildrdata(name, rdata, dtype, buf, &ds);
if (result != ISC_R_SUCCESS)
- fatal("can't build DS");
+ fatal("can't build record");
+
+ result = dns_name_totext(name, ISC_FALSE, &nameb);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't print name");
+
+ /* Add lookaside origin, if set */
+ if (lookaside != NULL) {
+ if (isc_buffer_availablelength(&nameb) < strlen(lookaside))
+ fatal("DLV origin '%s' is too long", lookaside);
+ isc_buffer_putstr(&nameb, lookaside);
+ if (lookaside[strlen(lookaside) - 1] != '.') {
+ if (isc_buffer_availablelength(&nameb) < 1)
+ fatal("DLV origin '%s' is too long", lookaside);
+ isc_buffer_putstr(&nameb, ".");
+ }
+ }
result = dns_rdata_totext(&ds, (dns_name_t *) NULL, &textb);
if (result != ISC_R_SUCCESS)
- fatal("can't print DS rdata");
+ fatal("can't print rdata");
result = dns_rdataclass_totext(rdclass, &classb);
if (result != ISC_R_SUCCESS)
- fatal("can't print DS class");
+ fatal("can't print class");
- result = dns_name_print(name, stdout);
- if (result != ISC_R_SUCCESS)
- fatal("can't print DS name");
+ isc_buffer_usedregion(&nameb, &r);
+ isc_util_fwrite(r.base, 1, r.length, stdout);
putchar(' ');
isc_buffer_usedregion(&classb, &r);
isc_util_fwrite(r.base, 1, r.length, stdout);
- printf(" DS ");
+ if (lookaside == NULL)
+ printf(" DS ");
+ else
+ printf(" DLV ");
isc_buffer_usedregion(&textb, &r);
isc_util_fwrite(r.base, 1, r.length, stdout);
putchar('\n');
}
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
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",
+ fprintf(stderr, " %s options [-K dir] keyfile\n\n", program);
+ fprintf(stderr, " %s options [-K dir] [-c class] -s dnsname\n\n",
program);
+ fprintf(stderr, " %s options -f zonefile (as zone name)\n\n", program);
+ fprintf(stderr, " %s options -f zonefile zonename\n\n", program);
fprintf(stderr, "Version: %s\n", VERSION);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -v <verbose level>\n");
+ fprintf(stderr, " -K <directory>: directory in which to find "
+ "key file or keyset file\n");
+ fprintf(stderr, " -a algorithm: digest algorithm "
+ "(SHA-1, SHA-256 or GOST)\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");
+ fprintf(stderr, " -l: add lookaside zone and print DLV records\n");
+ fprintf(stderr, " -s: read keyset from keyset-<dnsname> file\n");
+ fprintf(stderr, " -c class: rdata class for DS set (default: IN)\n");
+ fprintf(stderr, " -f file: read keyset from zone file\n");
+ fprintf(stderr, " -A: when used with -f, "
+ "include all keys in DS set, not just KSKs\n");
+ fprintf(stderr, "Output: DS or DLV 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;
+ char *algname = NULL, *classname = NULL;
+ char *filename = NULL, *dir = NULL, *namestr;
+ char *lookaside = NULL;
+ char *endp;
+ int ch;
+ unsigned int dtype = DNS_DSDIGEST_SHA1;
+ isc_boolean_t both = ISC_TRUE;
+ isc_boolean_t usekeyset = ISC_FALSE;
+ isc_boolean_t showall = ISC_FALSE;
+ isc_result_t result;
+ isc_log_t *log = NULL;
+ isc_entropy_t *ectx = NULL;
+ dns_rdataset_t rdataset;
+ dns_rdata_t rdata;
dns_rdata_init(&rdata);
@@ -275,7 +344,7 @@ main(int argc, char **argv) {
isc_commandline_errprint = ISC_FALSE;
while ((ch = isc_commandline_parse(argc, argv,
- "12a:c:d:sv:h")) != -1) {
+ "12Aa:c:d:Ff:K:l:sv:h")) != -1) {
switch (ch) {
case '1':
dtype = DNS_DSDIGEST_SHA1;
@@ -285,6 +354,9 @@ main(int argc, char **argv) {
dtype = DNS_DSDIGEST_SHA256;
both = ISC_FALSE;
break;
+ case 'A':
+ showall = ISC_TRUE;
+ break;
case 'a':
algname = isc_commandline_argument;
both = ISC_FALSE;
@@ -293,7 +365,21 @@ main(int argc, char **argv) {
classname = isc_commandline_argument;
break;
case 'd':
- dirname = isc_commandline_argument;
+ fprintf(stderr, "%s: the -d option is deprecated; "
+ "use -K\n", program);
+ /* fall through */
+ case 'K':
+ dir = isc_commandline_argument;
+ if (strlen(dir) == 0U)
+ fatal("directory must be non-empty string");
+ break;
+ case 'f':
+ filename = isc_commandline_argument;
+ break;
+ case 'l':
+ lookaside = isc_commandline_argument;
+ if (strlen(lookaside) == 0U)
+ fatal("lookaside must be a non-empty string");
break;
case 's':
usekeyset = ISC_TRUE;
@@ -303,11 +389,14 @@ main(int argc, char **argv) {
if (*endp != '\0')
fatal("-v must be followed by a number");
break;
+ case 'F':
+ /* Reserved for FIPS mode */
+ /* FALLTHROUGH */
case '?':
if (isc_commandline_option != '?')
fprintf(stderr, "%s: invalid argument -%c\n",
program, isc_commandline_option);
- /* Falls into */
+ /* FALLTHROUGH */
case 'h':
usage();
@@ -325,13 +414,24 @@ main(int argc, char **argv) {
else if (strcasecmp(algname, "SHA256") == 0 ||
strcasecmp(algname, "SHA-256") == 0)
dtype = DNS_DSDIGEST_SHA256;
+#ifdef HAVE_OPENSSL_GOST
+ else if (strcasecmp(algname, "GOST") == 0)
+ dtype = DNS_DSDIGEST_GOST;
+#endif
else
fatal("unknown algorithm %s", algname);
}
rdclass = strtoclass(classname);
- if (argc < isc_commandline_index + 1)
+ if (usekeyset && filename != NULL)
+ fatal("cannot use both -s and -f");
+
+ /* When not using -f, -A is implicit */
+ if (filename == NULL)
+ showall = ISC_TRUE;
+
+ if (argc < isc_commandline_index + 1 && filename == NULL)
fatal("the key file name was not specified");
if (argc > isc_commandline_index + 1)
fatal("extraneous arguments");
@@ -344,28 +444,50 @@ main(int argc, char **argv) {
result = dst_lib_init(mctx, ectx,
ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
if (result != ISC_R_SUCCESS)
- fatal("could not initialize dst");
+ fatal("could not initialize dst: %s",
+ isc_result_totext(result));
isc_entropy_stopcallbacksources(ectx);
setup_logging(verbose, mctx, &log);
- if (usekeyset) {
- loadkeys(dirname, argv[isc_commandline_index]);
+ dns_rdataset_init(&rdataset);
+
+ if (usekeyset || filename != NULL) {
+ if (argc < isc_commandline_index + 1 && filename != NULL) {
+ /* using zone name as the zone file name */
+ namestr = filename;
+ } else
+ namestr = argv[isc_commandline_index];
- for (result = dns_rdataset_first(&keyset);
+ result = initname(namestr);
+ if (result != ISC_R_SUCCESS)
+ fatal("could not initialize name %s", namestr);
+
+ if (usekeyset)
+ result = loadkeyset(dir, &rdataset);
+ else
+ result = loadsetfromfile(filename, &rdataset);
+
+ if (result != ISC_R_SUCCESS)
+ fatal("could not load DNSKEY set: %s\n",
+ isc_result_totext(result));
+
+ for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&keyset)) {
+ result = dns_rdataset_next(&rdataset)) {
dns_rdata_init(&rdata);
- dns_rdataset_current(&keyset, &rdata);
+ dns_rdataset_current(&rdataset, &rdata);
if (verbose > 2)
logkey(&rdata);
if (both) {
- emitds(DNS_DSDIGEST_SHA1, &rdata);
- emitds(DNS_DSDIGEST_SHA256, &rdata);
+ emit(DNS_DSDIGEST_SHA1, showall, lookaside,
+ &rdata);
+ emit(DNS_DSDIGEST_SHA256, showall, lookaside,
+ &rdata);
} else
- emitds(dtype, &rdata);
+ emit(dtype, showall, lookaside, &rdata);
}
} else {
unsigned char key_buf[DST_KEY_MAXSIZE];
@@ -374,18 +496,14 @@ main(int argc, char **argv) {
DST_KEY_MAXSIZE, &rdata);
if (both) {
- emitds(DNS_DSDIGEST_SHA1, &rdata);
- emitds(DNS_DSDIGEST_SHA256, &rdata);
+ emit(DNS_DSDIGEST_SHA1, showall, lookaside, &rdata);
+ emit(DNS_DSDIGEST_SHA256, showall, lookaside, &rdata);
} else
- emitds(dtype, &rdata);
+ emit(dtype, showall, lookaside, &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);
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
cleanup_logging(&log);
dst_lib_destroy();
isc_hash_destroy();
diff --git a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.docbook b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.docbook
index c4ea38d..36410d5 100644
--- a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.docbook
+++ b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2008-2010 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
@@ -17,10 +17,10 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-dsfromkey.docbook,v 1.6 2008-11-07 13:54:11 jreed Exp $ -->
+<!-- $Id: dnssec-dsfromkey.docbook,v 1.12 2010-12-23 23:47:08 tbox Exp $ -->
<refentry id="man.dnssec-dsfromkey">
<refentryinfo>
- <date>November 29, 2008</date>
+ <date>August 26, 2009</date>
</refentryinfo>
<refmeta>
@@ -37,6 +37,8 @@
<docinfo>
<copyright>
<year>2008</year>
+ <year>2009</year>
+ <year>2010</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -48,17 +50,22 @@
<arg><option>-1</option></arg>
<arg><option>-2</option></arg>
<arg><option>-a <replaceable class="parameter">alg</replaceable></option></arg>
+ <arg><option>-l <replaceable class="parameter">domain</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>-K <replaceable class="parameter">directory</replaceable></option></arg>
+ <arg><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
+ <arg><option>-s</option></arg>
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
- <arg><option>-d <replaceable class="parameter">dir</replaceable></option></arg>
+ <arg><option>-f <replaceable class="parameter">file</replaceable></option></arg>
+ <arg><option>-A</option></arg>
+ <arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
<arg choice="req">dnsname</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -99,17 +106,55 @@
<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.
+ <option>algorithm</option> must be one of SHA-1 (SHA1),
+ SHA-256 (SHA256) or GOST. These values are case insensitive.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>-v <replaceable class="parameter">level</replaceable></term>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
<listitem>
<para>
- Sets the debugging level.
+ Look for key files (or, in keyset mode,
+ <filename>keyset-</filename> files) in
+ <option>directory</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-f <replaceable class="parameter">file</replaceable></term>
+ <listitem>
+ <para>
+ Zone file mode: in place of the keyfile name, the argument is
+ the DNS domain name of a zone master file, which can be read
+ from <option>file</option>. If the zone name is the same as
+ <option>file</option>, then it may be omitted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-A</term>
+ <listitem>
+ <para>
+ Include ZSK's when generating DS records. Without this option,
+ only keys which have the KSK flag set will be converted to DS
+ records and printed. Useful only in zone file mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-l <replaceable class="parameter">domain</replaceable></term>
+ <listitem>
+ <para>
+ Generate a DLV set instead of a DS set. The specified
+ <option>domain</option> is appended to the name for each
+ record in the set.
+ The DNSSEC Lookaside Validation (DLV) RR is described
+ in RFC 4431.
</para>
</listitem>
</varlistentry>
@@ -119,8 +164,7 @@
<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.
+ the DNS domain name of a keyset file.
</para>
</listitem>
</varlistentry>
@@ -129,23 +173,20 @@
<term>-c <replaceable class="parameter">class</replaceable></term>
<listitem>
<para>
- Specifies the DNS class (default is IN), useful only
- in the keyset mode.
+ Specifies the DNS class (default is IN). Useful only
+ in keyset or zone file mode.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>-d <replaceable class="parameter">directory</replaceable></term>
+ <term>-v <replaceable class="parameter">level</replaceable></term>
<listitem>
<para>
- Look for <filename>keyset</filename> files in
- <option>directory</option> as the directory, ignored when
- not in the keyset mode.
+ Sets the debugging level.
</para>
</listitem>
</varlistentry>
-
</variablelist>
</refsect1>
@@ -197,6 +238,7 @@
</citerefentry>,
<citetitle>BIND 9 Administrator Reference Manual</citetitle>,
<citetitle>RFC 3658</citetitle>,
+ <citetitle>RFC 4431</citetitle>.
<citetitle>RFC 4509</citetitle>.
</para>
</refsect1>
diff --git a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.html b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.html
index 6186481..54cc1ab 100644
--- a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.html
+++ b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2008-2010 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
@@ -13,7 +13,7 @@
- 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.14.1 2010-05-19 02:06:11 tbox Exp $ -->
+<!-- $Id: dnssec-dsfromkey.html,v 1.13 2010-12-24 01:14:19 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -28,18 +28,18 @@
</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 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>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] {keyfile}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> {-s} [<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">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-s</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>file</code></em></code>] [<code class="option">-A</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {dnsname}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543424"></a><h2>DESCRIPTION</h2>
+<a name="id2543464"></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>
+<a name="id2543476"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-1</span></dt>
<dd><p>
@@ -53,34 +53,54 @@
<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.
+ <code class="option">algorithm</code> must be one of SHA-1 (SHA1),
+ SHA-256 (SHA256) or GOST. These values are case insensitive.
</p></dd>
-<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
<dd><p>
- Sets the debugging level.
+ Look for key files (or, in keyset mode,
+ <code class="filename">keyset-</code> files) in
+ <code class="option">directory</code>.
+ </p></dd>
+<dt><span class="term">-f <em class="replaceable"><code>file</code></em></span></dt>
+<dd><p>
+ Zone file mode: in place of the keyfile name, the argument is
+ the DNS domain name of a zone master file, which can be read
+ from <code class="option">file</code>. If the zone name is the same as
+ <code class="option">file</code>, then it may be omitted.
+ </p></dd>
+<dt><span class="term">-A</span></dt>
+<dd><p>
+ Include ZSK's when generating DS records. Without this option,
+ only keys which have the KSK flag set will be converted to DS
+ records and printed. Useful only in zone file mode.
+ </p></dd>
+<dt><span class="term">-l <em class="replaceable"><code>domain</code></em></span></dt>
+<dd><p>
+ Generate a DLV set instead of a DS set. The specified
+ <code class="option">domain</code> is appended to the name for each
+ record in the set.
+ The DNSSEC Lookaside Validation (DLV) RR is described
+ in RFC 4431.
</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.
+ the DNS domain name of a keyset file.
</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.
+ Specifies the DNS class (default is IN). Useful only
+ in keyset or zone file mode.
</p></dd>
-<dt><span class="term">-d <em class="replaceable"><code>directory</code></em></span></dt>
+<dt><span class="term">-v <em class="replaceable"><code>level</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.
+ Sets the debugging level.
</p></dd>
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543563"></a><h2>EXAMPLE</h2>
+<a name="id2543662"></a><h2>EXAMPLE</h2>
<p>
To build the SHA-256 DS RR from the
<strong class="userinput"><code>Kexample.com.+003+26160</code></strong>
@@ -95,7 +115,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543593"></a><h2>FILES</h2>
+<a name="id2543692"></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
@@ -109,22 +129,23 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543628"></a><h2>CAVEAT</h2>
+<a name="id2543728"></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>
+<a name="id2543737"></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 4431</em>.
<em class="citetitle">RFC 4509</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543674"></a><h2>AUTHOR</h2>
+<a name="id2543777"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8 b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8
index 45fc087..d8c19f2 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2008-2011 Internet Systems Consortium, Inc. ("ISC")
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
.\" 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.14.3 2010-01-16 01:55:32 tbox Exp $
+.\" $Id: dnssec-keyfromlabel.8,v 1.18.14.1.2.1 2011-06-09 03:41:05 tbox Exp $
.\"
.hy 0
.ad l
@@ -32,18 +32,22 @@
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}
+\fBdnssec\-keyfromlabel\fR {\-l\ \fIlabel\fR} [\fB\-3\fR] [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-k\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-y\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.
+.PP
+The
+\fBname\fR
+of the key is specified on the command line. This must match the name of the zone for which the key is being generated.
.SH "OPTIONS"
.PP
\-a \fIalgorithm\fR
.RS 4
Selects the cryptographic algorithm. The value of
\fBalgorithm\fR
-must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or DH (Diffie Hellman). These values are case insensitive.
+must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST. These values are case insensitive.
.sp
If no algorithm is specified, then RSASHA1 will be used by default, unless the
\fB\-3\fR
@@ -56,9 +60,19 @@ Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA
Note 2: DH automatically sets the \-k flag.
.RE
.PP
+\-3
+.RS 4
+Use an NSEC3\-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default.
+.RE
+.PP
+\-E \fIengine\fR
+.RS 4
+Specifies the name of the crypto hardware (OpenSSL engine). When compiled with PKCS#11 support it defaults to "pkcs11".
+.RE
+.PP
\-l \fIlabel\fR
.RS 4
-Specifies the label of keys in the crypto hardware (PKCS#11 device).
+Specifies the label of the key pair in the crypto hardware. The label may be preceded by an optional OpenSSL engine name, separated by a colon, as in "pkcs11:keylabel".
.RE
.PP
\-n \fInametype\fR
@@ -68,6 +82,15 @@ Specifies the owner type of the key. The value of
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
+.RS 4
+Compatibility mode: generates an old\-style key, without any metadata. By default,
+\fBdnssec\-keyfromlabel\fR
+will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the
+\fB\-C\fR
+option suppresses them.
+.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.
@@ -75,13 +98,23 @@ Indicates that the DNS record containing the key should have the specified class
.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.
+Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE.
+.RE
+.PP
+\-G
+.RS 4
+Generate a key, but do not publish it or sign with it. This option is incompatible with \-P and \-A.
.RE
.PP
\-h
.RS 4
Prints a short summary of the options and arguments to
-\fBdnssec\-keygen\fR.
+\fBdnssec\-keyfromlabel\fR.
+.RE
+.PP
+\-K \fIdirectory\fR
+.RS 4
+Sets the directory in which the key files are to be written.
.RE
.PP
\-k
@@ -91,7 +124,7 @@ Generate KEY records rather than DNSKEY records.
.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.
+Sets the protocol value for the 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
@@ -105,6 +138,39 @@ must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF.
.RS 4
Sets the debugging level.
.RE
+.PP
+\-y
+.RS 4
+Allows DNSSEC key files to be generated even if the key ID would collide with that of an existing key, in the event of either key being revoked. (This is only safe to use if you are sure you won't be using RFC 5011 trust anchor maintenance with either of the keys involved.)
+.RE
+.SH "TIMING OPTIONS"
+.PP
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds.
+.PP
+\-P \fIdate/offset\fR
+.RS 4
+Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-A \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-R \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.
+.RE
+.PP
+\-I \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.
+.RE
+.PP
+\-D \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)
+.RE
.SH "GENERATED KEY FILES"
.PP
When
@@ -138,7 +204,7 @@ file contains a DNS KEY record that can be inserted into a zone file (directly o
.PP
The
\fI.private\fR
-file contains algorithm specific fields. For obvious security reasons, this file does not have general read permission.
+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),
@@ -149,5 +215,5 @@ RFC 4034.
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2008\-2011 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c
index 8e9a53b..323f918 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2007-2010 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
@@ -14,12 +14,13 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-keyfromlabel.c,v 1.4.50.2 2010-01-15 23:47:31 tbox Exp $ */
+/* $Id: dnssec-keyfromlabel.c,v 1.32 2010-12-23 04:07:59 marka Exp $ */
/*! \file */
#include <config.h>
+#include <ctype.h>
#include <stdlib.h>
#include <isc/buffer.h>
@@ -27,9 +28,11 @@
#include <isc/entropy.h>
#include <isc/mem.h>
#include <isc/region.h>
+#include <isc/print.h>
#include <isc/string.h>
#include <isc/util.h>
+#include <dns/dnssec.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
#include <dns/log.h>
@@ -47,35 +50,60 @@
const char *program = "dnssec-keyfromlabel";
int verbose;
+#define DEFAULT_ALGORITHM "RSASHA1"
+#define DEFAULT_NSEC3_ALGORITHM "NSEC3RSASHA1"
+
static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 |"
" NSEC3DSA | NSEC3RSASHA1 |"
- " RSASHA256 | RSASHA512";
+ " RSASHA256 | RSASHA512 | ECCGOST";
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
static void
usage(void) {
fprintf(stderr, "Usage:\n");
- fprintf(stderr, " %s -a alg -l label [options] name\n\n",
+ fprintf(stderr, " %s -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, " -l label: label of the key pair\n");
fprintf(stderr, " name: owner of the key\n");
fprintf(stderr, "Other options:\n");
+ fprintf(stderr, " -a algorithm: %s\n", algs);
+ fprintf(stderr, " (default: RSASHA1, or "
+ "NSEC3RSASHA1 if using -3)\n");
+ fprintf(stderr, " -3: use NSEC3-capable algorithm\n");
+ fprintf(stderr, " -c class (default: IN)\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, " -E enginename (default: pkcs11)\n");
+#else
+ fprintf(stderr, " -E enginename\n");
+#endif
+ fprintf(stderr, " -f keyflag: KSK | REVOKE\n");
+ fprintf(stderr, " -K directory: directory in which to place "
+ "key files\n");
+ fprintf(stderr, " -k: generate a TYPE=KEY key\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>: "
+ fprintf(stderr, " -p protocol: default: 3 [dnssec]\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, " -y: permit keys that might collide\n");
+ fprintf(stderr, " -v verbose level\n");
+ fprintf(stderr, "Date options:\n");
+ fprintf(stderr, " -P date/[+-]offset: set key publication date\n");
+ fprintf(stderr, " -A date/[+-]offset: set key activation date\n");
+ fprintf(stderr, " -R date/[+-]offset: set key revocation date\n");
+ fprintf(stderr, " -I date/[+-]offset: set key inactivation date\n");
+ fprintf(stderr, " -D date/[+-]offset: set key deletion date\n");
+ fprintf(stderr, " -G: generate key only; do not set -P or -A\n");
+ fprintf(stderr, " -C: generate a backward-compatible key, omitting"
+ " all dates\n");
fprintf(stderr, "Output:\n");
fprintf(stderr, " K<name>+<alg>+<id>.key, "
- "K<name>+<alg>+<id>.private\n");
+ "K<name>+<alg>+<id>.private\n");
exit (-1);
}
@@ -83,14 +111,20 @@ usage(void) {
int
main(int argc, char **argv) {
char *algname = NULL, *nametype = NULL, *type = NULL;
+ const char *directory = NULL;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
char *classname = NULL;
char *endp;
- dst_key_t *key = NULL, *oldkey;
+ dst_key_t *key = NULL;
dns_fixedname_t fname;
dns_name_t *name;
- isc_uint16_t flags = 0, ksk = 0;
+ isc_uint16_t flags = 0, kskflag = 0, revflag = 0;
dns_secalg_t alg;
- isc_boolean_t null_key = ISC_FALSE;
+ isc_boolean_t oldstyle = ISC_FALSE;
isc_mem_t *mctx = NULL;
int ch;
int protocol = -1, signatory = 0;
@@ -103,6 +137,20 @@ main(int argc, char **argv) {
dns_rdataclass_t rdclass;
int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC;
char *label = NULL;
+ isc_stdtime_t publish = 0, activate = 0, revoke = 0;
+ isc_stdtime_t inactive = 0, delete = 0;
+ isc_stdtime_t now;
+ isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
+ isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE;
+ isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
+ isc_boolean_t genonly = ISC_FALSE;
+ isc_boolean_t use_nsec3 = ISC_FALSE;
+ isc_boolean_t avoid_collisions = ISC_TRUE;
+ isc_boolean_t exact;
+ unsigned char c;
if (argc == 1)
usage();
@@ -113,28 +161,49 @@ main(int argc, char **argv) {
isc_commandline_errprint = ISC_FALSE;
+ isc_stdtime_get(&now);
+
while ((ch = isc_commandline_parse(argc, argv,
- "a:c:f:kl:n:p:t:v:h")) != -1)
+ "3a:Cc:E:f:K:kl:n:p:t:v:yFhGP:A:R:I:D:")) != -1)
{
switch (ch) {
+ case '3':
+ use_nsec3 = ISC_TRUE;
+ break;
case 'a':
algname = isc_commandline_argument;
break;
+ case 'C':
+ oldstyle = ISC_TRUE;
+ break;
case 'c':
classname = isc_commandline_argument;
break;
+ case 'E':
+ engine = isc_commandline_argument;
+ break;
case 'f':
- if (strcasecmp(isc_commandline_argument, "KSK") == 0)
- ksk = DNS_KEYFLAG_KSK;
+ c = (unsigned char)(isc_commandline_argument[0]);
+ if (toupper(c) == 'K')
+ kskflag = DNS_KEYFLAG_KSK;
+ else if (toupper(c) == 'R')
+ revflag = DNS_KEYFLAG_REVOKE;
else
fatal("unknown flag '%s'",
isc_commandline_argument);
break;
+ case 'K':
+ directory = isc_commandline_argument;
+ ret = try_dir(directory);
+ if (ret != ISC_R_SUCCESS)
+ fatal("cannot open directory %s: %s",
+ directory, isc_result_totext(ret));
+ break;
case 'k':
options |= DST_TYPE_KEY;
break;
case 'l':
- label = isc_commandline_argument;
+ label = isc_mem_strdup(mctx, isc_commandline_argument);
break;
case 'n':
nametype = isc_commandline_argument;
@@ -153,11 +222,80 @@ main(int argc, char **argv) {
if (*endp != '\0')
fatal("-v must be followed by a number");
break;
-
+ case 'y':
+ avoid_collisions = ISC_FALSE;
+ break;
+ case 'G':
+ genonly = ISC_TRUE;
+ break;
+ case 'P':
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setpub = ISC_TRUE;
+ publish = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetpub = ISC_TRUE;
+ }
+ break;
+ case 'A':
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setact = ISC_TRUE;
+ activate = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetact = ISC_TRUE;
+ }
+ break;
+ case 'R':
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setrev = ISC_TRUE;
+ revoke = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetrev = ISC_TRUE;
+ }
+ break;
+ case 'I':
+ if (setinact || unsetinact)
+ fatal("-I specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setinact = ISC_TRUE;
+ inactive = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetinact = ISC_TRUE;
+ }
+ break;
+ case 'D':
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setdel = ISC_TRUE;
+ delete = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetdel = ISC_TRUE;
+ }
+ break;
+ case 'F':
+ /* Reserved for FIPS mode */
+ /* FALLTHROUGH */
case '?':
if (isc_commandline_option != '?')
fprintf(stderr, "%s: invalid argument -%c\n",
program, isc_commandline_option);
+ /* FALLTHROUGH */
case 'h':
usage();
@@ -170,10 +308,11 @@ main(int argc, char **argv) {
if (ectx == NULL)
setup_entropy(mctx, NULL, &ectx);
- ret = dst_lib_init(mctx, ectx,
- ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ ret = dst_lib_init2(mctx, ectx, engine,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
if (ret != ISC_R_SUCCESS)
- fatal("could not initialize dst");
+ fatal("could not initialize dst: %s",
+ isc_result_totext(ret));
setup_logging(verbose, mctx, &log);
@@ -184,8 +323,30 @@ main(int argc, char **argv) {
if (argc > isc_commandline_index + 1)
fatal("extraneous arguments");
- if (algname == NULL)
- fatal("no algorithm was specified");
+ if (strchr(label, ':') == NULL &&
+ engine != NULL && strlen(engine) != 0U) {
+ char *l;
+ int len;
+
+ len = strlen(label) + strlen(engine) + 2;
+ l = isc_mem_allocate(mctx, len);
+ if (l == NULL)
+ fatal("cannot allocate memory");
+ snprintf(l, len, "%s:%s", engine, label);
+ isc_mem_free(mctx, label);
+ label = l;
+ }
+
+ if (algname == NULL) {
+ if (use_nsec3)
+ algname = strdup(DEFAULT_NSEC3_ALGORITHM);
+ else
+ algname = strdup(DEFAULT_ALGORITHM);
+ if (verbose > 0)
+ fprintf(stderr, "no algorithm specified; "
+ "defaulting to %s\n", algname);
+ }
+
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 "
@@ -201,6 +362,14 @@ main(int argc, char **argv) {
options |= DST_TYPE_KEY;
}
+ if (use_nsec3 &&
+ alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 &&
+ alg != DST_ALG_RSASHA256 && alg != DST_ALG_RSASHA512 &&
+ alg != DST_ALG_ECCGOST) {
+ fatal("%s is incompatible with NSEC3; "
+ "do not use the -3 option", algname);
+ }
+
if (type != NULL && (options & DST_TYPE_KEY) != 0) {
if (strcasecmp(type, "NOAUTH") == 0)
flags |= DNS_KEYTYPE_NOAUTH;
@@ -234,10 +403,15 @@ main(int argc, char **argv) {
rdclass = strtoclass(classname);
+ if (directory == NULL)
+ directory = ".";
+
if ((options & DST_TYPE_KEY) != 0) /* KEY */
flags |= signatory;
- else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */
- flags |= ksk;
+ else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */
+ flags |= kskflag;
+ flags |= revflag;
+ }
if (protocol == -1)
protocol = DNS_KEYPROTO_DNSSEC;
@@ -260,53 +434,108 @@ main(int argc, char **argv) {
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);
+ ret = dns_name_fromtext(name, &buf, dns_rootname, 0, 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);
+ rdclass, engine, label, NULL, mctx, &key);
isc_entropy_stopcallbacksources(ectx);
if (ret != ISC_R_SUCCESS) {
char namestr[DNS_NAME_FORMATSIZE];
- char algstr[ALG_FORMATSIZE];
+ char algstr[DNS_SECALG_FORMATSIZE];
dns_name_format(name, namestr, sizeof(namestr));
- alg_format(alg, algstr, sizeof(algstr));
- fatal("failed to generate key %s/%s: %s\n",
+ dns_secalg_format(alg, algstr, sizeof(algstr));
+ fatal("failed to get key %s/%s: %s\n",
namestr, algstr, isc_result_totext(ret));
+ /* NOTREACHED */
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.
+ * Set key timing metadata (unless using -C)
+ *
+ * Publish and activation dates are set to "now" by default, but
+ * can be overridden. Creation date is always set to "now".
*/
- 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) {
+ if (!oldstyle) {
+ dst_key_settime(key, DST_TIME_CREATED, now);
+
+ if (genonly && (setpub || setact))
+ fatal("cannot use -G together with -P or -A options");
+
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, publish);
+ else if (setact)
+ dst_key_settime(key, DST_TIME_PUBLISH, activate);
+ else if (!genonly && !unsetpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, now);
+
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, activate);
+ else if (!genonly && !unsetact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, now);
+
+ if (setrev) {
+ if (kskflag == 0)
+ fprintf(stderr, "%s: warning: Key is "
+ "not flagged as a KSK, but -R "
+ "was used. Revoking a ZSK is "
+ "legal, but undefined.\n",
+ program);
+ dst_key_settime(key, DST_TIME_REVOKE, revoke);
+ }
+
+ if (setinact)
+ dst_key_settime(key, DST_TIME_INACTIVE, inactive);
+
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE, delete);
+ } else {
+ if (setpub || setact || setrev || setinact ||
+ setdel || unsetpub || unsetact ||
+ unsetrev || unsetinact || unsetdel || genonly)
+ fatal("cannot use -C together with "
+ "-P, -A, -R, -I, -D, or -G options");
+ /*
+ * Compatibility mode: Private-key-format
+ * should be set to 1.2.
+ */
+ dst_key_setprivateformat(key, 1, 2);
+ }
+
+ /*
+ * Do not overwrite an existing key. Warn LOUDLY if there
+ * is a risk of ID collision due to this key or another key
+ * being revoked.
+ */
+ if (key_collision(dst_key_id(key), name, directory, alg, mctx, &exact))
+ {
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_buildfilename(key, 0, directory, &buf);
+ if (exact)
+ fatal("%s: %s already exists\n", program, filename);
+
+ if (avoid_collisions)
+ fatal("%s: %s could collide with another key upon "
+ "revokation\n", program, filename);
+
+ fprintf(stderr, "%s: WARNING: Key %s could collide with "
+ "another key upon revokation. If you plan "
+ "to revoke keys, destroy this key and "
+ "generate a different one.\n",
+ program, filename);
}
- ret = dst_key_tofile(key, options, NULL);
+ ret = dst_key_tofile(key, options, directory);
if (ret != ISC_R_SUCCESS) {
- char keystr[KEY_FORMATSIZE];
- key_format(key, keystr, sizeof(keystr));
+ char keystr[DST_KEY_FORMATSIZE];
+ dst_key_format(key, keystr, sizeof(keystr));
fatal("failed to write key %s: %s\n", keystr,
isc_result_totext(ret));
}
@@ -322,6 +551,7 @@ main(int argc, char **argv) {
dns_name_destroy();
if (verbose > 10)
isc_mem_stats(mctx, stdout);
+ isc_mem_free(mctx, label);
isc_mem_destroy(&mctx);
return (0);
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook
index a2fff5a..be38a24 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2008-2011 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keyfromlabel.docbook,v 1.6.14.2 2010-01-15 23:47:31 tbox Exp $ -->
+<!-- $Id: dnssec-keyfromlabel.docbook,v 1.18.14.1.2.1 2011-06-02 23:47:27 tbox Exp $ -->
<refentry id="man.dnssec-keyfromlabel">
<refentryinfo>
<date>February 8, 2008</date>
@@ -37,7 +37,9 @@
<docinfo>
<copyright>
<year>2008</year>
+ <year>2009</year>
<year>2010</year>
+ <year>2011</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -45,15 +47,25 @@
<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>-3</option></arg>
+ <arg><option>-a <replaceable class="parameter">algorithm</replaceable></option></arg>
+ <arg><option>-A <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
+ <arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
<arg><option>-f <replaceable class="parameter">flag</replaceable></option></arg>
+ <arg><option>-G</option></arg>
+ <arg><option>-I <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-k</option></arg>
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
<arg><option>-n <replaceable class="parameter">nametype</replaceable></option></arg>
+ <arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-p <replaceable class="parameter">protocol</replaceable></option></arg>
+ <arg><option>-R <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-t <replaceable class="parameter">type</replaceable></option></arg>
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-y</option></arg>
<arg choice="req">name</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -65,6 +77,11 @@
key files for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034.
</para>
+ <para>
+ The <option>name</option> of the key is specified on the command
+ line. This must match the name of the zone for which the key is
+ being generated.
+ </para>
</refsect1>
<refsect1>
@@ -76,9 +93,8 @@
<listitem>
<para>
Selects the cryptographic algorithm. The value of
- <option>algorithm</option> must be one of RSAMD5,
- RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256,
- RSASHA512 or DH (Diffie Hellman).
+ <option>algorithm</option> must be one of RSAMD5, RSASHA1,
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
These values are case insensitive.
</para>
<para>
@@ -99,11 +115,34 @@
</varlistentry>
<varlistentry>
+ <term>-3</term>
+ <listitem>
+ <para>
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-E <replaceable class="parameter">engine</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the name of the crypto hardware (OpenSSL engine).
+ When compiled with PKCS#11 support it defaults to "pkcs11".
+ </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).
+ Specifies the label of the key pair in the crypto hardware.
+ The label may be preceded by an optional OpenSSL engine name,
+ separated by a colon, as in "pkcs11:keylabel".
</para>
</listitem>
</varlistentry>
@@ -117,8 +156,22 @@
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.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-C</term>
+ <listitem>
+ <para>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <command>dnssec-keyfromlabel</command>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <option>-C</option> option suppresses them.
</para>
</listitem>
</varlistentry>
@@ -138,7 +191,17 @@
<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.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-G</term>
+ <listitem>
+ <para>
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
</para>
</listitem>
</varlistentry>
@@ -148,7 +211,16 @@
<listitem>
<para>
Prints a short summary of the options and arguments to
- <command>dnssec-keygen</command>.
+ <command>dnssec-keyfromlabel</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ Sets the directory in which the key files are to be written.
</para>
</listitem>
</varlistentry>
@@ -166,7 +238,7 @@
<term>-p <replaceable class="parameter">protocol</replaceable></term>
<listitem>
<para>
- Sets the protocol value for the generated key. The protocol
+ Sets the protocol value for the 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.
@@ -195,6 +267,93 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>-y</term>
+ <listitem>
+ <para>
+ Allows DNSSEC key files to be generated even if the key ID
+ would collide with that of an existing key, in the event of
+ either key being revoked. (This is only safe to use if you
+ are sure you won't be using RFC 5011 trust anchor maintenance
+ with either of the keys involved.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>TIMING OPTIONS</title>
+
+ <para>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-P <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-A <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-R <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-I <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-D <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -214,8 +373,7 @@
</listitem>
<listitem>
<para><filename>aaa</filename> is the numeric representation
- of the
- algorithm.
+ of the algorithm.
</para>
</listitem>
<listitem>
@@ -229,8 +387,7 @@
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.
+ private key.
</para>
<para>
The <filename>.key</filename> file contains a DNS KEY record
@@ -239,8 +396,8 @@
statement).
</para>
<para>
- The <filename>.private</filename> file contains algorithm
- specific
+ The <filename>.private</filename> file contains
+ algorithm-specific
fields. For obvious security reasons, this file does not have
general read permission.
</para>
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html
index ad2a562..2b1b236 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2008-2011 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -13,7 +13,7 @@
- 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.44.3 2010-01-16 01:55:32 tbox Exp $ -->
+<!-- $Id: dnssec-keyfromlabel.html,v 1.17.14.1.2.1 2011-06-09 03:41:05 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -28,26 +28,30 @@
</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 class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-3</code>] [<code class="option">-a <em class="replaceable"><code>algorithm</code></em></code>] [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-G</code>] [<code class="option">-I <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-k</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-R <em class="replaceable"><code>date/offset</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>] [<code class="option">-y</code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543416"></a><h2>DESCRIPTION</h2>
+<a name="id2543494"></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>
+<p>
+ The <code class="option">name</code> of the key is specified on the command
+ line. This must match the name of the zone for which the key is
+ being generated.
+ </p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543428"></a><h2>OPTIONS</h2>
+<a name="id2543512"></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,
- RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256,
- RSASHA512 or DH (Diffie Hellman).
+ <code class="option">algorithm</code> must be one of RSAMD5, RSASHA1,
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
These values are case insensitive.
</p>
<p>
@@ -65,10 +69,23 @@
Note 2: DH automatically sets the -k flag.
</p>
</dd>
+<dt><span class="term">-3</span></dt>
+<dd><p>
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default.
+ </p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Specifies the name of the crypto hardware (OpenSSL engine).
+ When compiled with PKCS#11 support it defaults to "pkcs11".
+ </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).
+ Specifies the label of the key pair in the crypto hardware.
+ The label may be preceded by an optional OpenSSL engine name,
+ separated by a colon, as in "pkcs11:keylabel".
</p></dd>
<dt><span class="term">-n <em class="replaceable"><code>nametype</code></em></span></dt>
<dd><p>
@@ -77,8 +94,17 @@
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.
+ </p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <span><strong class="command">dnssec-keyfromlabel</strong></span>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <code class="option">-C</code> option suppresses them.
</p></dd>
<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
<dd><p>
@@ -88,12 +114,21 @@
<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.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+ </p></dd>
+<dt><span class="term">-G</span></dt>
+<dd><p>
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
</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>.
+ <span><strong class="command">dnssec-keyfromlabel</strong></span>.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to be written.
</p></dd>
<dt><span class="term">-k</span></dt>
<dd><p>
@@ -101,7 +136,7 @@
</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
+ Sets the protocol value for the 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.
@@ -117,10 +152,65 @@
<dd><p>
Sets the debugging level.
</p></dd>
+<dt><span class="term">-y</span></dt>
+<dd><p>
+ Allows DNSSEC key files to be generated even if the key ID
+ would collide with that of an existing key, in the event of
+ either key being revoked. (This is only safe to use if you
+ are sure you won't be using RFC 5011 trust anchor maintenance
+ with either of the keys involved.)
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543876"></a><h2>TIMING OPTIONS</h2>
+<p>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+ </p></dd>
+<dt><span class="term">-A <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+ </p></dd>
+<dt><span class="term">-R <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </p></dd>
+<dt><span class="term">-I <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </p></dd>
+<dt><span class="term">-D <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </p></dd>
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543632"></a><h2>GENERATED KEY FILES</h2>
+<a name="id2544042"></a><h2>GENERATED KEY FILES</h2>
<p>
When <span><strong class="command">dnssec-keyfromlabel</strong></span> completes
successfully,
@@ -132,8 +222,7 @@
<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.
+ of the algorithm.
</p></li>
<li><p><code class="filename">iiiii</code> is the key identifier (or
footprint).
@@ -144,8 +233,7 @@
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.
+ private key.
</p>
<p>
The <code class="filename">.key</code> file contains a DNS KEY record
@@ -154,14 +242,14 @@
statement).
</p>
<p>
- The <code class="filename">.private</code> file contains algorithm
- specific
+ 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="id2543704"></a><h2>SEE ALSO</h2>
+<a name="id2544115"></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>,
@@ -169,7 +257,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543737"></a><h2>AUTHOR</h2>
+<a name="id2544148"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.8 b/contrib/bind9/bin/dnssec/dnssec-keygen.8
index c4be24e..ea4690e 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.40.44.4 2010-01-16 01:55:32 tbox Exp $
+.\" $Id: dnssec-keygen.8,v 1.55 2010-12-24 01:14:19 tbox Exp $
.\"
.hy 0
.ad l
@@ -33,11 +33,11 @@
dnssec\-keygen \- DNSSEC key generation tool
.SH "SYNOPSIS"
.HP 14
-\fBdnssec\-keygen\fR {\-a\ \fIalgorithm\fR} {\-b\ \fIkeysize\fR} {\-n\ \fInametype\fR} [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-e\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-k\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {name}
+\fBdnssec\-keygen\fR [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-b\ \fR\fB\fIkeysize\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-3\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-C\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-e\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-k\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-q\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\ \fR\fB\fIkey\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] {name}
.SH "DESCRIPTION"
.PP
\fBdnssec\-keygen\fR
-generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures), as defined in RFC 2845.
+generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY (Transaction Key) as defined in RFC 2930.
.PP
The
\fBname\fR
@@ -48,16 +48,28 @@ of the key is specified on the command line. For DNSSEC keys, this must match th
.RS 4
Selects the cryptographic algorithm. For DNSSEC keys, the value of
\fBalgorithm\fR
-must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC\-MD5, HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256, HMAC\-SHA384, or HMAC\-SHA512. These values are case insensitive.
+must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC\-MD5, HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256, HMAC\-SHA384, or HMAC\-SHA512. These values are case insensitive.
+.sp
+If no algorithm is specified, then RSASHA1 will be used by default, unless the
+\fB\-3\fR
+option is specified, in which case NSEC3RSASHA1 will be used instead. (If
+\fB\-3\fR
+is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.)
.sp
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC\-MD5 is mandatory.
.sp
-Note 2: HMAC\-MD5 and DH automatically set the \-k flag.
+Note 2: DH, HMAC\-MD5, and HMAC\-SHA1 through HMAC\-SHA512 automatically set the \-T KEY option.
.RE
.PP
\-b \fIkeysize\fR
.RS 4
Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSA keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC keys must be between 1 and 512 bits.
+.sp
+The key size does not need to be specified if using a default algorithm. The default key size is 1024 bits for zone signing keys (ZSK's) and 2048 bits for key signing keys (KSK's, generated with
+\fB\-f KSK\fR). However, if an algorithm is explicitly specified with the
+\fB\-a\fR, then there is no default key size, and the
+\fB\-b\fR
+must be used.
.RE
.PP
\-n \fInametype\fR
@@ -67,11 +79,30 @@ Specifies the owner type of the key. The value of
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
+\-3
+.RS 4
+Use an NSEC3\-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default. Note that RSASHA256, RSASHA512 and ECCGOST algorithms are NSEC3\-capable.
+.RE
+.PP
+\-C
+.RS 4
+Compatibility mode: generates an old\-style key, without any metadata. By default,
+\fBdnssec\-keygen\fR
+will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the
+\fB\-C\fR
+option suppresses them.
+.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
+\-E \fIengine\fR
+.RS 4
+Uses a crypto hardware (OpenSSL engine) for random number and, when supported, key generation. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine.
+.RE
+.PP
\-e
.RS 4
If generating an RSAMD5/RSASHA1 key, use a large exponent.
@@ -79,7 +110,12 @@ If generating an RSAMD5/RSASHA1 key, use a large exponent.
.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.
+Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE.
+.RE
+.PP
+\-G
+.RS 4
+Generate a key, but do not publish it or sign with it. This option is incompatible with \-P and \-A.
.RE
.PP
\-g \fIgenerator\fR
@@ -93,9 +129,14 @@ Prints a short summary of the options and arguments to
\fBdnssec\-keygen\fR.
.RE
.PP
+\-K \fIdirectory\fR
+.RS 4
+Sets the directory in which the key files are to be written.
+.RE
+.PP
\-k
.RS 4
-Generate KEY records rather than DNSKEY records.
+Deprecated in favor of \-T KEY.
.RE
.PP
\-p \fIprotocol\fR
@@ -103,6 +144,15 @@ Generate KEY records rather than DNSKEY records.
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
+\-q
+.RS 4
+Quiet mode: Suppresses unnecessary output, including progress indication. Without this option, when
+\fBdnssec\-keygen\fR
+is run interactively to generate an RSA or DSA key pair, it will print a string of symbols to
+\fIstderr\fR
+indicating the progress of the key generation. A '.' indicates that a random number has been found which passed an initial sieve test; '+' means a number has passed a single round of the Miller\-Rabin primality test; a space means that the number has passed all the tests and is a satisfactory key.
+.RE
+.PP
\-r \fIrandomdev\fR
.RS 4
Specifies the source of randomness. If the operating system does not provide a
@@ -114,11 +164,24 @@ specifies the name of a character device or file containing random data to be us
indicates that keyboard input should be used.
.RE
.PP
+\-S \fIkey\fR
+.RS 4
+Create a new key which is an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the existing key. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.
+.RE
+.PP
\-s \fIstrength\fR
.RS 4
Specifies the strength value of the key. The strength is a number between 0 and 15, and currently has no defined purpose in DNSSEC.
.RE
.PP
+\-T \fIrrtype\fR
+.RS 4
+Specifies the resource record type to use for the key.
+\fBrrtype\fR
+must be either DNSKEY or KEY. The default is DNSKEY when using a DNSSEC algorithm, but it can be overridden to KEY for use with SIG(0).
+Using any TSIG algorithm (HMAC\-* or DH) forces this option to KEY.
+.RE
+.PP
\-t \fItype\fR
.RS 4
Indicates the use of the key.
@@ -130,6 +193,43 @@ must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF.
.RS 4
Sets the debugging level.
.RE
+.SH "TIMING OPTIONS"
+.PP
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds.
+.PP
+\-P \fIdate/offset\fR
+.RS 4
+Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-A \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-R \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.
+.RE
+.PP
+\-I \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.
+.RE
+.PP
+\-D \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)
+.RE
+.PP
+\-i \fIinterval\fR
+.RS 4
+Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.
+.sp
+If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.
+.sp
+As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.
+.RE
.SH "GENERATED KEYS"
.PP
When
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.c b/contrib/bind9/bin/dnssec/dnssec-keygen.c
index 2184122..f369326 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keygen.c
+++ b/contrib/bind9/bin/dnssec/dnssec-keygen.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2010 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
@@ -29,13 +29,15 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-keygen.c,v 1.81.48.2 2010-01-15 23:47:31 tbox Exp $ */
+/* $Id: dnssec-keygen.c,v 1.115 2010-12-23 04:07:59 marka Exp $ */
/*! \file */
#include <config.h>
+#include <ctype.h>
#include <stdlib.h>
+#include <unistd.h>
#include <isc/buffer.h>
#include <isc/commandline.h>
@@ -45,6 +47,7 @@
#include <isc/string.h>
#include <isc/util.h>
+#include <dns/dnssec.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
#include <dns/log.h>
@@ -62,103 +65,224 @@
const char *program = "dnssec-keygen";
int verbose;
-static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 | RSASHA256 |"
- " RSASHA512 | NSEC3DSA | NSEC3RSASHA1 | HMAC-MD5 |"
- " HMAC-SHA1 | HMAC-SHA224 | HMAC-SHA256 |"
- " HMAC-SHA384 | HMAC-SHA512";
+#define DEFAULT_ALGORITHM "RSASHA1"
+#define DEFAULT_NSEC3_ALGORITHM "NSEC3RSASHA1"
-static isc_boolean_t
-dsa_size_ok(int size) {
- return (ISC_TF(size >= 512 && size <= 1024 && size % 64 == 0));
-}
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void progress(int p);
static void
usage(void) {
fprintf(stderr, "Usage:\n");
- fprintf(stderr, " %s -a alg -b bits [-n type] [options] name\n\n",
- program);
+ fprintf(stderr, " %s [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, " -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, " RSASHA256:\t[512..%d]\n", MAX_RSA);
- fprintf(stderr, " RSASHA512:\t[1024..%d]\n", MAX_RSA);
+ fprintf(stderr, " name: owner of the key\n");
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -K <directory>: write keys into directory\n");
+ fprintf(stderr, " -a <algorithm>:\n");
+ fprintf(stderr, " RSA | RSAMD5 | DSA | RSASHA1 | NSEC3RSASHA1"
+ " | NSEC3DSA |\n");
+ fprintf(stderr, " RSASHA256 | RSASHA512 | ECCGOST |\n");
+ fprintf(stderr, " DH | HMAC-MD5 | HMAC-SHA1 | HMAC-SHA224 | "
+ "HMAC-SHA256 | \n");
+ fprintf(stderr, " HMAC-SHA384 | HMAC-SHA512\n");
+ fprintf(stderr, " (default: RSASHA1, or "
+ "NSEC3RSASHA1 if using -3)\n");
+ fprintf(stderr, " -3: use NSEC3-capable algorithm\n");
+ fprintf(stderr, " -b <key size in bits>:\n");
+ fprintf(stderr, " RSAMD5:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " RSASHA1:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " NSEC3RSASHA1:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " RSASHA256:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " RSASHA512:\t[1024..%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, " NSEC3DSA:\t[512..1024] and divisible "
+ "by 64\n");
+ fprintf(stderr, " ECCGOST:\tignored\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");
fprintf(stderr, " HMAC-SHA256:\t[1..256]\n");
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");
+ fprintf(stderr, " (if using the default algorithm, key size\n"
+ " defaults to 2048 for KSK, or 1024 for all "
+ "others)\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, " -d <digest bits> (0 => max, default)\n");
- fprintf(stderr, " -e use large exponent (RSAMD5/RSASHA1 only)\n");
- fprintf(stderr, " -f keyflag: KSK\n");
- fprintf(stderr, " -g <generator> use specified generator "
- "(DH only)\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, " -E <engine name> (default \"pkcs11\")\n");
+#else
+ fprintf(stderr, " -E <engine name>\n");
+#endif
+ fprintf(stderr, " -e: use large exponent (RSAMD5/RSASHA1 only)\n");
+ fprintf(stderr, " -f <keyflag>: KSK | REVOKE\n");
+ fprintf(stderr, " -g <generator>: use specified generator "
+ "(DH only)\n");
+ fprintf(stderr, " -p <protocol>: (default: 3 [dnssec])\n");
+ fprintf(stderr, " -s <strength>: strength value this key signs DNS "
+ "records with (default: 0)\n");
+ fprintf(stderr, " -T <rrtype>: DNSKEY | KEY (default: DNSKEY; "
+ "use KEY for SIG(0))\n");
+ fprintf(stderr, " ECCGOST:\tignored\n");
fprintf(stderr, " -t <type>: "
- "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
- "(default: AUTHCONF)\n");
- fprintf(stderr, " -p <protocol>: "
- "default: 3 [dnssec]\n");
- fprintf(stderr, " -s <strength> strength value this key signs DNS "
- "records with (default: 0)\n");
+ "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
+ "(default: AUTHCONF)\n");
fprintf(stderr, " -r <randomdev>: a file containing random data\n");
- fprintf(stderr, " -v <verbose level>\n");
- fprintf(stderr, " -k : generate a TYPE=KEY key\n");
+
+ fprintf(stderr, " -h: print usage and exit\n");
+ fprintf(stderr, " -m <memory debugging mode>:\n");
+ fprintf(stderr, " usage | trace | record | size | mctx\n");
+ fprintf(stderr, " -v <level>: set verbosity level (0 - 10)\n");
+ fprintf(stderr, "Timing options:\n");
+ fprintf(stderr, " -P date/[+-]offset/none: set key publication date "
+ "(default: now)\n");
+ fprintf(stderr, " -A date/[+-]offset/none: set key activation date "
+ "(default: now)\n");
+ fprintf(stderr, " -R date/[+-]offset/none: set key "
+ "revocation date\n");
+ fprintf(stderr, " -I date/[+-]offset/none: set key "
+ "inactivation date\n");
+ fprintf(stderr, " -D date/[+-]offset/none: set key deletion date\n");
+ fprintf(stderr, " -G: generate key only; do not set -P or -A\n");
+ fprintf(stderr, " -C: generate a backward-compatible key, omitting "
+ "all dates\n");
+ fprintf(stderr, " -S <key>: generate a successor to an existing "
+ "key\n");
+ fprintf(stderr, " -i <interval>: prepublication interval for "
+ "successor key "
+ "(default: 30 days)\n");
fprintf(stderr, "Output:\n");
fprintf(stderr, " K<name>+<alg>+<id>.key, "
- "K<name>+<alg>+<id>.private\n");
+ "K<name>+<alg>+<id>.private\n");
exit (-1);
}
+static isc_boolean_t
+dsa_size_ok(int size) {
+ return (ISC_TF(size >= 512 && size <= 1024 && size % 64 == 0));
+}
+
+static void
+progress(int p)
+{
+ char c = '*';
+
+ switch (p) {
+ case 0:
+ c = '.';
+ break;
+ case 1:
+ c = '+';
+ break;
+ case 2:
+ c = '*';
+ break;
+ case 3:
+ c = ' ';
+ break;
+ default:
+ break;
+ }
+ (void) putc(c, stderr);
+ (void) fflush(stderr);
+}
+
int
main(int argc, char **argv) {
char *algname = NULL, *nametype = NULL, *type = NULL;
char *classname = NULL;
char *endp;
- dst_key_t *key = NULL, *oldkey;
+ dst_key_t *key = NULL;
dns_fixedname_t fname;
dns_name_t *name;
- isc_uint16_t flags = 0, ksk = 0;
+ isc_uint16_t flags = 0, kskflag = 0, revflag = 0;
dns_secalg_t alg;
isc_boolean_t conflict = ISC_FALSE, null_key = ISC_FALSE;
+ isc_boolean_t oldstyle = ISC_FALSE;
isc_mem_t *mctx = NULL;
int ch, rsa_exp = 0, generator = 0, param = 0;
int protocol = -1, size = -1, signatory = 0;
isc_result_t ret;
isc_textregion_t r;
char filename[255];
+ const char *directory = NULL;
+ const char *predecessor = NULL;
+ dst_key_t *prevkey = NULL;
isc_buffer_t buf;
isc_log_t *log = NULL;
isc_entropy_t *ectx = NULL;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
dns_rdataclass_t rdclass;
int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC;
int dbits = 0;
+ isc_boolean_t use_default = ISC_FALSE, use_nsec3 = ISC_FALSE;
+ isc_stdtime_t publish = 0, activate = 0, revoke = 0;
+ isc_stdtime_t inactive = 0, delete = 0;
+ isc_stdtime_t now;
+ int prepub = -1;
+ isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
+ isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE;
+ isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
+ isc_boolean_t genonly = ISC_FALSE;
+ isc_boolean_t quiet = ISC_FALSE;
+ isc_boolean_t show_progress = ISC_FALSE;
+ unsigned char c;
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:b:c:d:ef:g:kn:t:p:s:r:v:h")) != -1)
- {
+ /*
+ * Process memory debugging argument first.
+ */
+#define CMDLINE_FLAGS "3A:a:b:Cc:D:d:E:eFf:Gg:hI:i:K:km:n:P:p:qR:r:S:s:T:t:v:"
+ 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;
+
+ RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
+
+ isc_stdtime_get(&now);
+
+ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
switch (ch) {
+ case '3':
+ use_nsec3 = ISC_TRUE;
+ break;
case 'a':
algname = isc_commandline_argument;
break;
@@ -167,6 +291,9 @@ main(int argc, char **argv) {
if (*endp != '\0' || size < 0)
fatal("-b requires a non-negative number");
break;
+ case 'C':
+ oldstyle = ISC_TRUE;
+ break;
case 'c':
classname = isc_commandline_argument;
break;
@@ -175,12 +302,18 @@ main(int argc, char **argv) {
if (*endp != '\0' || dbits < 0)
fatal("-d requires a non-negative number");
break;
+ case 'E':
+ engine = isc_commandline_argument;
+ break;
case 'e':
rsa_exp = 1;
break;
case 'f':
- if (strcasecmp(isc_commandline_argument, "KSK") == 0)
- ksk = DNS_KEYFLAG_KSK;
+ c = (unsigned char)(isc_commandline_argument[0]);
+ if (toupper(c) == 'K')
+ kskflag = DNS_KEYFLAG_KSK;
+ else if (toupper(c) == 'R')
+ revflag = DNS_KEYFLAG_REVOKE;
else
fatal("unknown flag '%s'",
isc_commandline_argument);
@@ -191,14 +324,22 @@ main(int argc, char **argv) {
if (*endp != '\0' || generator <= 0)
fatal("-g requires a positive number");
break;
+ case 'K':
+ directory = isc_commandline_argument;
+ ret = try_dir(directory);
+ if (ret != ISC_R_SUCCESS)
+ fatal("cannot open directory %s: %s",
+ directory, isc_result_totext(ret));
+ break;
case 'k':
- options |= DST_TYPE_KEY;
+ fatal("The -k option has been deprecated.\n"
+ "To generate a key-signing key, use -f KSK.\n"
+ "To generate a key with TYPE=KEY, use -T KEY.\n");
break;
case 'n':
nametype = isc_commandline_argument;
break;
- case 't':
- type = isc_commandline_argument;
+ case 'm':
break;
case 'p':
protocol = strtol(isc_commandline_argument, &endp, 10);
@@ -206,6 +347,12 @@ main(int argc, char **argv) {
fatal("-p must be followed by a number "
"[0..255]");
break;
+ case 'q':
+ quiet = ISC_TRUE;
+ break;
+ case 'r':
+ setup_entropy(mctx, isc_commandline_argument, &ectx);
+ break;
case 's':
signatory = strtol(isc_commandline_argument,
&endp, 10);
@@ -213,8 +360,19 @@ main(int argc, char **argv) {
fatal("-s must be followed by a number "
"[0..15]");
break;
- case 'r':
- setup_entropy(mctx, isc_commandline_argument, &ectx);
+ case 'T':
+ if (strcasecmp(isc_commandline_argument, "KEY") == 0)
+ options |= DST_TYPE_KEY;
+ else if (strcasecmp(isc_commandline_argument,
+ "DNSKEY") == 0)
+ /* default behavior */
+ ;
+ else
+ fatal("unknown type '%s'",
+ isc_commandline_argument);
+ break;
+ case 't':
+ type = isc_commandline_argument;
break;
case 'v':
endp = NULL;
@@ -222,11 +380,86 @@ main(int argc, char **argv) {
if (*endp != '\0')
fatal("-v must be followed by a number");
break;
-
+ case 'z':
+ /* already the default */
+ break;
+ case 'G':
+ genonly = ISC_TRUE;
+ break;
+ case 'P':
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setpub = ISC_TRUE;
+ publish = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetpub = ISC_TRUE;
+ }
+ break;
+ case 'A':
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setact = ISC_TRUE;
+ activate = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetact = ISC_TRUE;
+ }
+ break;
+ case 'R':
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setrev = ISC_TRUE;
+ revoke = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetrev = ISC_TRUE;
+ }
+ break;
+ case 'I':
+ if (setinact || unsetinact)
+ fatal("-I specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setinact = ISC_TRUE;
+ inactive = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetinact = ISC_TRUE;
+ }
+ break;
+ case 'D':
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setdel = ISC_TRUE;
+ delete = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetdel = ISC_TRUE;
+ }
+ break;
+ case 'S':
+ predecessor = isc_commandline_argument;
+ break;
+ case 'i':
+ prepub = strtottl(isc_commandline_argument);
+ break;
+ case 'F':
+ /* Reserved for FIPS mode */
+ /* FALLTHROUGH */
case '?':
if (isc_commandline_option != '?')
fprintf(stderr, "%s: invalid argument -%c\n",
program, isc_commandline_option);
+ /* FALLTHROUGH */
case 'h':
usage();
@@ -237,73 +470,219 @@ main(int argc, char **argv) {
}
}
+ if (!isatty(0))
+ quiet = ISC_TRUE;
+
if (ectx == NULL)
setup_entropy(mctx, NULL, &ectx);
- ret = dst_lib_init(mctx, ectx,
- ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ ret = dst_lib_init2(mctx, ectx, engine,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
if (ret != ISC_R_SUCCESS)
- fatal("could not initialize dst");
+ fatal("could not initialize dst: %s",
+ isc_result_totext(ret));
setup_logging(verbose, mctx, &log);
- 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 if (strcasecmp(algname, "HMAC-MD5") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACMD5;
- } else if (strcasecmp(algname, "HMAC-SHA1") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA1;
- } else if (strcasecmp(algname, "HMAC-SHA224") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA224;
- } else if (strcasecmp(algname, "HMAC-SHA256") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA256;
- } else if (strcasecmp(algname, "HMAC-SHA384") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA384;
- } else if (strcasecmp(algname, "HMAC-SHA512") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA512;
- } else {
- r.base = algname;
- r.length = strlen(algname);
- ret = dns_secalg_fromtext(&alg, &r);
+ if (predecessor == NULL) {
+ if (prepub == -1)
+ prepub = 0;
+
+ if (argc < isc_commandline_index + 1)
+ fatal("the key name was not specified");
+ if (argc > isc_commandline_index + 1)
+ fatal("extraneous arguments");
+
+ 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, 0, NULL);
if (ret != ISC_R_SUCCESS)
- fatal("unknown algorithm %s", algname);
- if (alg == DST_ALG_DH)
- options |= DST_TYPE_KEY;
- }
+ fatal("invalid key name %s: %s",
+ argv[isc_commandline_index],
+ isc_result_totext(ret));
+
+ if (algname == NULL) {
+ use_default = ISC_TRUE;
+ if (use_nsec3)
+ algname = strdup(DEFAULT_NSEC3_ALGORITHM);
+ else
+ algname = strdup(DEFAULT_ALGORITHM);
+ if (verbose > 0)
+ fprintf(stderr, "no algorithm specified; "
+ "defaulting to %s\n", algname);
+ }
- 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);
- if (size < 0)
- size = 0;
+ if (strcasecmp(algname, "RSA") == 0) {
+ fprintf(stderr, "The use of RSA (RSAMD5) is not "
+ "recommended.\nIf you still wish to "
+ "use RSA (RSAMD5) please specify "
+ "\"-a RSAMD5\"\n");
+ return (1);
+ } else if (strcasecmp(algname, "HMAC-MD5") == 0)
+ alg = DST_ALG_HMACMD5;
+ else if (strcasecmp(algname, "HMAC-SHA1") == 0)
+ alg = DST_ALG_HMACSHA1;
+ else if (strcasecmp(algname, "HMAC-SHA224") == 0)
+ alg = DST_ALG_HMACSHA224;
+ else if (strcasecmp(algname, "HMAC-SHA256") == 0)
+ alg = DST_ALG_HMACSHA256;
+ else if (strcasecmp(algname, "HMAC-SHA384") == 0)
+ alg = DST_ALG_HMACSHA384;
+ else if (strcasecmp(algname, "HMAC-SHA512") == 0)
+ alg = DST_ALG_HMACSHA512;
+ 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;
}
- else if (strcasecmp(type, "AUTHCONF") == 0)
- /* nothing */;
- else
- fatal("invalid type %s", type);
- }
- if (size < 0)
- fatal("key size not specified (-b option)");
+ if (use_nsec3 &&
+ alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 &&
+ alg != DST_ALG_RSASHA256 && alg!= DST_ALG_RSASHA512 &&
+ alg != DST_ALG_ECCGOST) {
+ fatal("%s is incompatible with NSEC3; "
+ "do not use the -3 option", algname);
+ }
+
+ 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);
+ if (size < 0)
+ size = 0;
+ }
+ else if (strcasecmp(type, "AUTHCONF") == 0)
+ /* nothing */;
+ else
+ fatal("invalid type %s", type);
+ }
+
+ if (size < 0) {
+ if (use_default) {
+ if ((kskflag & DNS_KEYFLAG_KSK) != 0)
+ size = 2048;
+ else
+ size = 1024;
+ if (verbose > 0)
+ fprintf(stderr, "key size not "
+ "specified; defaulting "
+ "to %d\n", size);
+ } else if (alg != DST_ALG_ECCGOST)
+ fatal("key size not specified (-b option)");
+ }
+
+ if (!oldstyle && prepub > 0) {
+ if (setpub && setact && (activate - prepub) < publish)
+ fatal("Activation and publication dates "
+ "are closer together than the\n\t"
+ "prepublication interval.");
+
+ if (!setpub && !setact) {
+ setpub = setact = ISC_TRUE;
+ publish = now;
+ activate = now + prepub;
+ } else if (setpub && !setact) {
+ setact = ISC_TRUE;
+ activate = publish + prepub;
+ } else if (setact && !setpub) {
+ setpub = ISC_TRUE;
+ publish = activate - prepub;
+ }
+
+ if ((activate - prepub) < now)
+ fatal("Time until activation is shorter "
+ "than the\n\tprepublication interval.");
+ }
+ } else {
+ char keystr[DST_KEY_FORMATSIZE];
+ isc_stdtime_t when;
+ int major, minor;
+
+ if (prepub == -1)
+ prepub = (30 * 86400);
+
+ if (algname != NULL)
+ fatal("-S and -a cannot be used together");
+ if (size >= 0)
+ fatal("-S and -b cannot be used together");
+ if (nametype != NULL)
+ fatal("-S and -n cannot be used together");
+ if (type != NULL)
+ fatal("-S and -t cannot be used together");
+ if (setpub || unsetpub)
+ fatal("-S and -P cannot be used together");
+ if (setact || unsetact)
+ fatal("-S and -A cannot be used together");
+ if (use_nsec3)
+ fatal("-S and -3 cannot be used together");
+ if (oldstyle)
+ fatal("-S and -C cannot be used together");
+ if (genonly)
+ fatal("-S and -G cannot be used together");
+
+ ret = dst_key_fromnamedfile(predecessor, directory,
+ DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
+ mctx, &prevkey);
+ if (ret != ISC_R_SUCCESS)
+ fatal("Invalid keyfile %s: %s",
+ filename, isc_result_totext(ret));
+ if (!dst_key_isprivate(prevkey))
+ fatal("%s is not a private key", filename);
+
+ name = dst_key_name(prevkey);
+ alg = dst_key_alg(prevkey);
+ size = dst_key_size(prevkey);
+ flags = dst_key_flags(prevkey);
+
+ dst_key_format(prevkey, keystr, sizeof(keystr));
+ dst_key_getprivateformat(prevkey, &major, &minor);
+ if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION)
+ fatal("Key %s has incompatible format version %d.%d\n\t"
+ "It is not possible to generate a successor key.",
+ keystr, major, minor);
+
+ ret = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when);
+ if (ret != ISC_R_SUCCESS)
+ fatal("Key %s has no activation date.\n\t"
+ "You must use dnssec-settime -A to set one "
+ "before generating a successor.", keystr);
+
+ ret = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &activate);
+ if (ret != ISC_R_SUCCESS)
+ fatal("Key %s has no inactivation date.\n\t"
+ "You must use dnssec-settime -I to set one "
+ "before generating a successor.", keystr);
+
+ publish = activate - prepub;
+ if (publish < now)
+ fatal("Key %s becomes inactive\n\t"
+ "sooner than the prepublication period "
+ "for the new key ends.\n\t"
+ "Either change the inactivation date with "
+ "dnssec-settime -I,\n\t"
+ "or use the -i option to set a shorter "
+ "prepublication interval.", keystr);
+
+ ret = dst_key_gettime(prevkey, DST_TIME_DELETE, &when);
+ if (ret != ISC_R_SUCCESS)
+ fprintf(stderr, "%s: WARNING: Key %s has no removal "
+ "date;\n\t it will remain in the zone "
+ "indefinitely after rollover.\n\t "
+ "You can use dnssec-settime -D to "
+ "change this.\n", program, keystr);
+
+ setpub = setact = ISC_TRUE;
+ }
switch (alg) {
case DNS_KEYALG_RSAMD5:
@@ -326,7 +705,10 @@ main(int argc, char **argv) {
if (size != 0 && !dsa_size_ok(size))
fatal("invalid DSS key size: %d", size);
break;
+ case DST_ALG_ECCGOST:
+ break;
case DST_ALG_HMACMD5:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 512)
fatal("HMAC-MD5 key size %d out of range", size);
if (dbits != 0 && (dbits < 80 || dbits > 128))
@@ -336,6 +718,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA1:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 160)
fatal("HMAC-SHA1 key size %d out of range", size);
if (dbits != 0 && (dbits < 80 || dbits > 160))
@@ -345,6 +728,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA224:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 224)
fatal("HMAC-SHA224 key size %d out of range", size);
if (dbits != 0 && (dbits < 112 || dbits > 224))
@@ -354,6 +738,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA256:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 256)
fatal("HMAC-SHA256 key size %d out of range", size);
if (dbits != 0 && (dbits < 128 || dbits > 256))
@@ -363,6 +748,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA384:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 384)
fatal("HMAC-384 key size %d out of range", size);
if (dbits != 0 && (dbits < 192 || dbits > 384))
@@ -372,6 +758,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA512:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 512)
fatal("HMAC-SHA512 key size %d out of range", size);
if (dbits != 0 && (dbits < 256 || dbits > 512))
@@ -384,7 +771,8 @@ main(int argc, char **argv) {
if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1 ||
alg == DNS_KEYALG_NSEC3RSASHA1 || alg == DNS_KEYALG_RSASHA256 ||
- alg == DNS_KEYALG_RSASHA512) && rsa_exp != 0)
+ alg == DNS_KEYALG_RSASHA512 || alg == DST_ALG_ECCGOST) &&
+ rsa_exp != 0)
fatal("specified RSA exponent for a non-RSA key");
if (alg != DNS_KEYALG_DH && generator != 0)
@@ -409,10 +797,15 @@ main(int argc, char **argv) {
rdclass = strtoclass(classname);
+ if (directory == NULL)
+ directory = ".";
+
if ((options & DST_TYPE_KEY) != 0) /* KEY / HMAC */
flags |= signatory;
- else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */
- flags |= ksk;
+ else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */
+ flags |= kskflag;
+ flags |= revflag;
+ }
if (protocol == -1)
protocol = DNS_KEYPROTO_DNSSEC;
@@ -435,16 +828,6 @@ main(int argc, char **argv) {
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));
-
switch(alg) {
case DNS_KEYALG_RSAMD5:
case DNS_KEYALG_RSASHA1:
@@ -452,12 +835,19 @@ main(int argc, char **argv) {
case DNS_KEYALG_RSASHA256:
case DNS_KEYALG_RSASHA512:
param = rsa_exp;
+ show_progress = ISC_TRUE;
break;
+
case DNS_KEYALG_DH:
param = generator;
break;
+
case DNS_KEYALG_DSA:
case DNS_KEYALG_NSEC3DSA:
+ case DST_ALG_ECCGOST:
+ show_progress = ISC_TRUE;
+ /* fall through */
+
case DST_ALG_HMACMD5:
case DST_ALG_HMACSHA1:
case DST_ALG_HMACSHA224:
@@ -475,62 +865,136 @@ main(int argc, char **argv) {
do {
conflict = ISC_FALSE;
- oldkey = NULL;
- /* generate the key */
- ret = dst_key_generate(name, alg, size, param, flags, protocol,
- rdclass, mctx, &key);
+ if (!quiet && show_progress) {
+ fprintf(stderr, "Generating key pair.");
+ ret = dst_key_generate2(name, alg, size, param, flags,
+ protocol, rdclass, mctx, &key,
+ &progress);
+ putc('\n', stderr);
+ fflush(stderr);
+ } else {
+ ret = dst_key_generate2(name, alg, size, param, flags,
+ protocol, rdclass, mctx, &key,
+ NULL);
+ }
+
isc_entropy_stopcallbacksources(ectx);
if (ret != ISC_R_SUCCESS) {
char namestr[DNS_NAME_FORMATSIZE];
- char algstr[ALG_FORMATSIZE];
+ char algstr[DNS_SECALG_FORMATSIZE];
dns_name_format(name, namestr, sizeof(namestr));
- alg_format(alg, algstr, sizeof(algstr));
+ dns_secalg_format(alg, algstr, sizeof(algstr));
fatal("failed to generate key %s/%s: %s\n",
namestr, algstr, isc_result_totext(ret));
+ /* NOTREACHED */
exit(-1);
}
dst_key_setbits(key, dbits);
/*
- * 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.
+ * Set key timing metadata (unless using -C)
+ *
+ * Creation date is always set to "now".
+ *
+ * For a new key without an explicit predecessor, publish
+ * and activation dates are set to "now" by default, but
+ * can both be overridden.
+ *
+ * For a successor key, activation is set to match the
+ * predecessor's inactivation date. Publish is set to 30
+ * days earlier than that (XXX: this should be configurable).
+ * If either of the resulting dates are in the past, that's
+ * an error; the inactivation date of the predecessor key
+ * must be updated before a successor key can be created.
*/
- 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) {
- dst_key_free(&oldkey);
+ if (!oldstyle) {
+ dst_key_settime(key, DST_TIME_CREATED, now);
+
+ if (genonly && (setpub || setact))
+ fatal("cannot use -G together with "
+ "-P or -A options");
+
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, publish);
+ else if (setact)
+ dst_key_settime(key, DST_TIME_PUBLISH,
+ activate);
+ else if (!genonly && !unsetpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, now);
+
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE,
+ activate);
+ else if (!genonly && !unsetact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, now);
+
+ if (setrev) {
+ if (kskflag == 0)
+ fprintf(stderr, "%s: warning: Key is "
+ "not flagged as a KSK, but -R "
+ "was used. Revoking a ZSK is "
+ "legal, but undefined.\n",
+ program);
+ dst_key_settime(key, DST_TIME_REVOKE, revoke);
+ }
+
+ if (setinact)
+ dst_key_settime(key, DST_TIME_INACTIVE,
+ inactive);
+
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE, delete);
+ } else {
+ if (setpub || setact || setrev || setinact ||
+ setdel || unsetpub || unsetact ||
+ unsetrev || unsetinact || unsetdel || genonly)
+ fatal("cannot use -C together with "
+ "-P, -A, -R, -I, -D, or -G options");
+ /*
+ * Compatibility mode: Private-key-format
+ * should be set to 1.2.
+ */
+ dst_key_setprivateformat(key, 1, 2);
+ }
+
+ /*
+ * Do not overwrite an existing key, or create a key
+ * if there is a risk of ID collision due to this key
+ * or another key being revoked.
+ */
+ if (key_collision(dst_key_id(key), name, directory,
+ alg, mctx, NULL)) {
conflict = ISC_TRUE;
- if (null_key)
+ if (null_key) {
+ dst_key_free(&key);
break;
- }
- if (conflict == ISC_TRUE) {
+ }
+
if (verbose > 0) {
isc_buffer_clear(&buf);
- ret = dst_key_buildfilename(key, 0, NULL, &buf);
+ dst_key_buildfilename(key, 0, directory, &buf);
fprintf(stderr,
- "%s: %s already exists, "
- "generating a new key\n",
+ "%s: %s already exists, or might "
+ "collide with another key upon "
+ "revokation. Generating a new key\n",
program, filename);
}
+
dst_key_free(&key);
}
-
} while (conflict == ISC_TRUE);
if (conflict)
- fatal("cannot generate a null key when a key with id 0 "
- "already exists");
+ fatal("cannot generate a null key due to possible key ID "
+ "collision");
- ret = dst_key_tofile(key, options, NULL);
+ ret = dst_key_tofile(key, options, directory);
if (ret != ISC_R_SUCCESS) {
- char keystr[KEY_FORMATSIZE];
- key_format(key, keystr, sizeof(keystr));
+ char keystr[DST_KEY_FORMATSIZE];
+ dst_key_format(key, keystr, sizeof(keystr));
fatal("failed to write key %s: %s\n", keystr,
isc_result_totext(ret));
}
@@ -539,6 +1003,8 @@ main(int argc, char **argv) {
ret = dst_key_buildfilename(key, 0, NULL, &buf);
printf("%s\n", filename);
dst_key_free(&key);
+ if (prevkey != NULL)
+ dst_key_free(&prevkey);
cleanup_logging(&log);
cleanup_entropy(&ectx);
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.docbook b/contrib/bind9/bin/dnssec/dnssec-keygen.docbook
index 5c7d164..dc140eb 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.22.44.4 2010-01-15 23:47:33 tbox Exp $ -->
+<!-- $Id: dnssec-keygen.docbook,v 1.36 2010-12-23 04:07:59 marka Exp $ -->
<refentry id="man.dnssec-keygen">
<refentryinfo>
<date>June 30, 2000</date>
@@ -57,20 +57,34 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>dnssec-keygen</command>
- <arg choice="req">-a <replaceable class="parameter">algorithm</replaceable></arg>
- <arg choice="req">-b <replaceable class="parameter">keysize</replaceable></arg>
- <arg choice="req">-n <replaceable class="parameter">nametype</replaceable></arg>
+ <arg><option>-a <replaceable class="parameter">algorithm</replaceable></option></arg>
+ <arg ><option>-b <replaceable class="parameter">keysize</replaceable></option></arg>
+ <arg><option>-n <replaceable class="parameter">nametype</replaceable></option></arg>
+ <arg><option>-3</option></arg>
+ <arg><option>-A <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-C</option></arg>
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
+ <arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
<arg><option>-e</option></arg>
<arg><option>-f <replaceable class="parameter">flag</replaceable></option></arg>
+ <arg><option>-G</option></arg>
<arg><option>-g <replaceable class="parameter">generator</replaceable></option></arg>
<arg><option>-h</option></arg>
+ <arg><option>-I <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-i <replaceable class="parameter">interval</replaceable></option></arg>
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
<arg><option>-k</option></arg>
+ <arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-p <replaceable class="parameter">protocol</replaceable></option></arg>
+ <arg><option>-q</option></arg>
+ <arg><option>-R <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-r <replaceable class="parameter">randomdev</replaceable></option></arg>
+ <arg><option>-S <replaceable class="parameter">key</replaceable></option></arg>
<arg><option>-s <replaceable class="parameter">strength</replaceable></option></arg>
<arg><option>-t <replaceable class="parameter">type</replaceable></option></arg>
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-z</option></arg>
<arg choice="req">name</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -80,7 +94,8 @@
<para><command>dnssec-keygen</command>
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034. It can also generate keys for use with
- TSIG (Transaction Signatures), as defined in RFC 2845.
+ TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY
+ (Transaction Key) as defined in RFC 2930.
</para>
<para>
The <option>name</option> of the key is specified on the command
@@ -99,19 +114,27 @@
<para>
Selects the cryptographic algorithm. For DNSSEC keys, the value
of <option>algorithm</option> must be one of RSAMD5, RSASHA1,
- DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512.
- For TSIG/TKEY, the value must
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
+ For TSIG/TKEY, the value must
be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224,
HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are
case insensitive.
</para>
<para>
+ If no algorithm is specified, then RSASHA1 will be used by
+ default, unless the <option>-3</option> option is specified,
+ in which case NSEC3RSASHA1 will be used instead. (If
+ <option>-3</option> is used and an algorithm is specified,
+ that algorithm will be checked for compatibility with NSEC3.)
+ </para>
+ <para>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is
mandatory.
</para>
<para>
- Note 2: HMAC-MD5 and DH automatically set the -k flag.
+ Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512
+ automatically set the -T KEY option.
</para>
</listitem>
</varlistentry>
@@ -127,6 +150,15 @@
bits and an exact multiple of 64. HMAC keys must be
between 1 and 512 bits.
</para>
+ <para>
+ The key size does not need to be specified if using a default
+ algorithm. The default key size is 1024 bits for zone signing
+ keys (ZSK's) and 2048 bits for key signing keys (KSK's,
+ generated with <option>-f KSK</option>). However, if an
+ algorithm is explicitly specified with the <option>-a</option>,
+ then there is no default key size, and the <option>-b</option>
+ must be used.
+ </para>
</listitem>
</varlistentry>
@@ -146,6 +178,34 @@
</varlistentry>
<varlistentry>
+ <term>-3</term>
+ <listitem>
+ <para>
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default. Note that RSASHA256, RSASHA512 and ECCGOST algorithms
+ are NSEC3-capable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-C</term>
+ <listitem>
+ <para>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <command>dnssec-keygen</command>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <option>-C</option> option suppresses them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-c <replaceable class="parameter">class</replaceable></term>
<listitem>
<para>
@@ -156,6 +216,18 @@
</varlistentry>
<varlistentry>
+ <term>-E <replaceable class="parameter">engine</replaceable></term>
+ <listitem>
+ <para>
+ Uses a crypto hardware (OpenSSL engine) for random number
+ and, when supported, key generation. When compiled with PKCS#11
+ support it defaults to pkcs11; the empty name resets it to
+ no engine.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-e</term>
<listitem>
<para>
@@ -169,7 +241,17 @@
<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.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-G</term>
+ <listitem>
+ <para>
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
</para>
</listitem>
</varlistentry>
@@ -197,10 +279,19 @@
</varlistentry>
<varlistentry>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ Sets the directory in which the key files are to be written.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-k</term>
<listitem>
<para>
- Generate KEY records rather than DNSKEY records.
+ Deprecated in favor of -T KEY.
</para>
</listitem>
</varlistentry>
@@ -218,6 +309,25 @@
</varlistentry>
<varlistentry>
+ <term>-q</term>
+ <listitem>
+ <para>
+ Quiet mode: Suppresses unnecessary output, including
+ progress indication. Without this option, when
+ <command>dnssec-keygen</command> is run interactively
+ to generate an RSA or DSA key pair, it will print a string
+ of symbols to <filename>stderr</filename> indicating the
+ progress of the key generation. A '.' indicates that a
+ random number has been found which passed an initial
+ sieve test; '+' means a number has passed a single
+ round of the Miller-Rabin primality test; a space
+ means that the number has passed all the tests and is
+ a satisfactory key.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-r <replaceable class="parameter">randomdev</replaceable></term>
<listitem>
<para>
@@ -235,6 +345,21 @@
</varlistentry>
<varlistentry>
+ <term>-S <replaceable class="parameter">key</replaceable></term>
+ <listitem>
+ <para>
+ Create a new key which is an explicit successor to an
+ existing key. The name, algorithm, size, and type of the
+ key will be set to match the existing key. The activation
+ date of the new key will be set to the inactivation date of
+ the existing one. The publication date will be set to the
+ activation date minus the prepublication interval, which
+ defaults to 30 days.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-s <replaceable class="parameter">strength</replaceable></term>
<listitem>
<para>
@@ -246,6 +371,22 @@
</varlistentry>
<varlistentry>
+ <term>-T <replaceable class="parameter">rrtype</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the resource record type to use for the key.
+ <option>rrtype</option> must be either DNSKEY or KEY. The
+ default is DNSKEY when using a DNSSEC algorithm, but it can be
+ overridden to KEY for use with SIG(0).
+ <para>
+ </para>
+ Using any TSIG algorithm (HMAC-* or DH) forces this option
+ to KEY.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-t <replaceable class="parameter">type</replaceable></term>
<listitem>
<para>
@@ -270,6 +411,109 @@
</refsect1>
<refsect1>
+ <title>TIMING OPTIONS</title>
+
+ <para>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-P <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-A <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-R <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-I <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-D <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-i <replaceable class="parameter">interval</replaceable></term>
+ <listitem>
+ <para>
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+ </para>
+ <para>
+ If the key is being created as an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+ </para>
+ <para>
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+
+ <refsect1>
<title>GENERATED KEYS</title>
<para>
When <command>dnssec-keygen</command> completes
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.html b/contrib/bind9/bin/dnssec/dnssec-keygen.html
index 7ca7d57..2f3a69b 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.32.44.4 2010-01-16 01:55:32 tbox Exp $ -->
+<!-- $Id: dnssec-keygen.html,v 1.47 2010-12-24 01:14:20 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,14 +29,15 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-keygen</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-b <em class="replaceable"><code>keysize</code></em>} {-n <em class="replaceable"><code>nametype</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-e</code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-g <em class="replaceable"><code>generator</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k</code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>strength</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 class="cmdsynopsis"><p><code class="command">dnssec-keygen</code> [<code class="option">-a <em class="replaceable"><code>algorithm</code></em></code>] [<code class="option">-b <em class="replaceable"><code>keysize</code></em></code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-3</code>] [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-C</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-e</code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-G</code>] [<code class="option">-g <em class="replaceable"><code>generator</code></em></code>] [<code class="option">-h</code>] [<code class="option">-I <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-k</code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-q</code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-S <em class="replaceable"><code>key</code></em></code>] [<code class="option">-s <em class="replaceable"><code>strength</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>] [<code class="option">-z</code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543483"></a><h2>DESCRIPTION</h2>
+<a name="id2543578"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keygen</strong></span>
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034. It can also generate keys for use with
- TSIG (Transaction Signatures), as defined in RFC 2845.
+ TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY
+ (Transaction Key) as defined in RFC 2930.
</p>
<p>
The <code class="option">name</code> of the key is specified on the command
@@ -45,37 +46,56 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543501"></a><h2>OPTIONS</h2>
+<a name="id2543596"></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. For DNSSEC keys, the value
of <code class="option">algorithm</code> must be one of RSAMD5, RSASHA1,
- DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512.
- For TSIG/TKEY, the value must
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
+ For TSIG/TKEY, the value must
be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224,
HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are
case insensitive.
</p>
<p>
+ If no algorithm is specified, then RSASHA1 will be used by
+ default, unless the <code class="option">-3</code> option is specified,
+ in which case NSEC3RSASHA1 will be used instead. (If
+ <code class="option">-3</code> is used and an algorithm is specified,
+ that algorithm will be checked for compatibility with NSEC3.)
+ </p>
+<p>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is
mandatory.
</p>
<p>
- Note 2: HMAC-MD5 and DH automatically set the -k flag.
+ Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512
+ automatically set the -T KEY option.
</p>
</dd>
<dt><span class="term">-b <em class="replaceable"><code>keysize</code></em></span></dt>
-<dd><p>
+<dd>
+<p>
Specifies the number of bits in the key. The choice of key
size depends on the algorithm used. RSA keys must be
between 512 and 2048 bits. Diffie Hellman keys must be between
128 and 4096 bits. DSA keys must be between 512 and 1024
bits and an exact multiple of 64. HMAC keys must be
between 1 and 512 bits.
- </p></dd>
+ </p>
+<p>
+ The key size does not need to be specified if using a default
+ algorithm. The default key size is 1024 bits for zone signing
+ keys (ZSK's) and 2048 bits for key signing keys (KSK's,
+ generated with <code class="option">-f KSK</code>). However, if an
+ algorithm is explicitly specified with the <code class="option">-a</code>,
+ then there is no default key size, and the <code class="option">-b</code>
+ must be used.
+ </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
@@ -86,11 +106,36 @@
These values are case insensitive. Defaults to ZONE for DNSKEY
generation.
</p></dd>
+<dt><span class="term">-3</span></dt>
+<dd><p>
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default. Note that RSASHA256, RSASHA512 and ECCGOST algorithms
+ are NSEC3-capable.
+ </p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <span><strong class="command">dnssec-keygen</strong></span>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <code class="option">-C</code> option suppresses them.
+ </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">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Uses a crypto hardware (OpenSSL engine) for random number
+ and, when supported, key generation. When compiled with PKCS#11
+ support it defaults to pkcs11; the empty name resets it to
+ no engine.
+ </p></dd>
<dt><span class="term">-e</span></dt>
<dd><p>
If generating an RSAMD5/RSASHA1 key, use a large exponent.
@@ -98,7 +143,12 @@
<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.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+ </p></dd>
+<dt><span class="term">-G</span></dt>
+<dd><p>
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
</p></dd>
<dt><span class="term">-g <em class="replaceable"><code>generator</code></em></span></dt>
<dd><p>
@@ -112,9 +162,13 @@
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 <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to be written.
+ </p></dd>
<dt><span class="term">-k</span></dt>
<dd><p>
- Generate KEY records rather than DNSKEY records.
+ Deprecated in favor of -T KEY.
</p></dd>
<dt><span class="term">-p <em class="replaceable"><code>protocol</code></em></span></dt>
<dd><p>
@@ -123,6 +177,20 @@
Other possible values for this argument are listed in
RFC 2535 and its successors.
</p></dd>
+<dt><span class="term">-q</span></dt>
+<dd><p>
+ Quiet mode: Suppresses unnecessary output, including
+ progress indication. Without this option, when
+ <span><strong class="command">dnssec-keygen</strong></span> is run interactively
+ to generate an RSA or DSA key pair, it will print a string
+ of symbols to <code class="filename">stderr</code> indicating the
+ progress of the key generation. A '.' indicates that a
+ random number has been found which passed an initial
+ sieve test; '+' means a number has passed a single
+ round of the Miller-Rabin primality test; a space
+ means that the number has passed all the tests and is
+ a satisfactory key.
+ </p></dd>
<dt><span class="term">-r <em class="replaceable"><code>randomdev</code></em></span></dt>
<dd><p>
Specifies the source of randomness. If the operating
@@ -135,12 +203,37 @@
<code class="filename">keyboard</code> indicates that keyboard
input should be used.
</p></dd>
+<dt><span class="term">-S <em class="replaceable"><code>key</code></em></span></dt>
+<dd><p>
+ Create a new key which is an explicit successor to an
+ existing key. The name, algorithm, size, and type of the
+ key will be set to match the existing key. The activation
+ date of the new key will be set to the inactivation date of
+ the existing one. The publication date will be set to the
+ activation date minus the prepublication interval, which
+ defaults to 30 days.
+ </p></dd>
<dt><span class="term">-s <em class="replaceable"><code>strength</code></em></span></dt>
<dd><p>
Specifies the strength value of the key. The strength is
a number between 0 and 15, and currently has no defined
purpose in DNSSEC.
</p></dd>
+<dt><span class="term">-T <em class="replaceable"><code>rrtype</code></em></span></dt>
+<dd>
+<p>
+ Specifies the resource record type to use for the key.
+ <code class="option">rrtype</code> must be either DNSKEY or KEY. The
+ default is DNSKEY when using a DNSSEC algorithm, but it can be
+ overridden to KEY for use with SIG(0).
+ </p>
+<p>
+ </p>
+<p>
+ Using any TSIG algorithm (HMAC-* or DH) forces this option
+ to KEY.
+ </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
@@ -155,7 +248,78 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543836"></a><h2>GENERATED KEYS</h2>
+<a name="id2544301"></a><h2>TIMING OPTIONS</h2>
+<p>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+ </p></dd>
+<dt><span class="term">-A <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+ </p></dd>
+<dt><span class="term">-R <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </p></dd>
+<dt><span class="term">-I <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </p></dd>
+<dt><span class="term">-D <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </p></dd>
+<dt><span class="term">-i <em class="replaceable"><code>interval</code></em></span></dt>
+<dd>
+<p>
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+ </p>
+<p>
+ If the key is being created as an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+ </p>
+<p>
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+ </p>
+</dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2544491"></a><h2>GENERATED KEYS</h2>
<p>
When <span><strong class="command">dnssec-keygen</strong></span> completes
successfully,
@@ -201,7 +365,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543918"></a><h2>EXAMPLE</h2>
+<a name="id2544642"></a><h2>EXAMPLE</h2>
<p>
To generate a 768-bit DSA key for the domain
<strong class="userinput"><code>example.com</code></strong>, the following command would be
@@ -222,7 +386,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544030"></a><h2>SEE ALSO</h2>
+<a name="id2544685"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 2539</em>,
@@ -231,7 +395,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544061"></a><h2>AUTHOR</h2>
+<a name="id2544716"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/bin/dnssec/dnssec-revoke.8 b/contrib/bind9/bin/dnssec/dnssec-revoke.8
new file mode 100644
index 0000000..d57b6aa
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-revoke.8
@@ -0,0 +1,83 @@
+.\" Copyright (C) 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-revoke.8,v 1.9 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: dnssec\-revoke
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: June 1, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "DNSSEC\-REVOKE" "8" "June 1, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+dnssec\-revoke \- Set the REVOKED bit on a DNSSEC key
+.SH "SYNOPSIS"
+.HP 14
+\fBdnssec\-revoke\fR [\fB\-hr\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\fR] {keyfile}
+.SH "DESCRIPTION"
+.PP
+\fBdnssec\-revoke\fR
+reads a DNSSEC key file, sets the REVOKED bit on the key as defined in RFC 5011, and creates a new pair of key files containing the now\-revoked key.
+.SH "OPTIONS"
+.PP
+\-h
+.RS 4
+Emit usage message and exit.
+.RE
+.PP
+\-K \fIdirectory\fR
+.RS 4
+Sets the directory in which the key files are to reside.
+.RE
+.PP
+\-r
+.RS 4
+After writing the new keyset files remove the original keyset files.
+.RE
+.PP
+\-v \fIlevel\fR
+.RS 4
+Sets the debugging level.
+.RE
+.PP
+\-E \fIengine\fR
+.RS 4
+Use the given OpenSSL engine. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine.
+.RE
+.PP
+\-f
+.RS 4
+Force overwrite: Causes
+\fBdnssec\-revoke\fR
+to write the new key pair even if a file already exists matching the algorithm and key ID of the revoked key.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBdnssec\-keygen\fR(8),
+BIND 9 Administrator Reference Manual,
+RFC 5011.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/contrib/bind9/bin/dnssec/dnssec-revoke.c b/contrib/bind9/bin/dnssec/dnssec-revoke.c
new file mode 100644
index 0000000..90e905c
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-revoke.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2009, 2010 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-revoke.c,v 1.22 2010-05-06 23:50:56 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <libgen.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <isc/buffer.h>
+#include <isc/commandline.h>
+#include <isc/entropy.h>
+#include <isc/file.h>
+#include <isc/hash.h>
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/keyvalues.h>
+#include <dns/result.h>
+
+#include <dst/dst.h>
+
+#include "dnssectool.h"
+
+const char *program = "dnssec-revoke";
+int verbose;
+
+static isc_mem_t *mctx = NULL;
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s [options] keyfile\n\n", program);
+ fprintf(stderr, "Version: %s\n", VERSION);
+#ifdef USE_PKCS11
+ fprintf(stderr, " -E engine: specify OpenSSL engine "
+ "(default \"pkcs11\")\n");
+#else
+ fprintf(stderr, " -E engine: specify OpenSSL engine\n");
+#endif
+ fprintf(stderr, " -f: force overwrite\n");
+ fprintf(stderr, " -K directory: use directory for key files\n");
+ fprintf(stderr, " -h: help\n");
+ fprintf(stderr, " -r: remove old keyfiles after "
+ "creating revoked version\n");
+ fprintf(stderr, " -v level: set level of verbosity\n");
+ fprintf(stderr, "Output:\n");
+ fprintf(stderr, " K<name>+<alg>+<new id>.key, "
+ "K<name>+<alg>+<new id>.private\n");
+
+ exit (-1);
+}
+
+int
+main(int argc, char **argv) {
+ isc_result_t result;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
+ char *filename = NULL, *dir = NULL;
+ char newname[1024], oldname[1024];
+ char keystr[DST_KEY_FORMATSIZE];
+ char *endp;
+ int ch;
+ isc_entropy_t *ectx = NULL;
+ dst_key_t *key = NULL;
+ isc_uint32_t flags;
+ isc_buffer_t buf;
+ isc_boolean_t force = ISC_FALSE;
+ isc_boolean_t remove = ISC_FALSE;
+
+ 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, "E:fK:rhv:")) != -1) {
+ switch (ch) {
+ case 'E':
+ engine = isc_commandline_argument;
+ break;
+ case 'f':
+ force = ISC_TRUE;
+ break;
+ case 'K':
+ /*
+ * We don't have to copy it here, but do it to
+ * simplify cleanup later
+ */
+ dir = isc_mem_strdup(mctx, isc_commandline_argument);
+ if (dir == NULL) {
+ fatal("Failed to allocate memory for "
+ "directory");
+ }
+ break;
+ case 'r':
+ remove = 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 (argc < isc_commandline_index + 1 ||
+ argv[isc_commandline_index] == NULL)
+ fatal("The key file name was not specified");
+ if (argc > isc_commandline_index + 1)
+ fatal("Extraneous arguments");
+
+ if (dir != NULL) {
+ filename = argv[isc_commandline_index];
+ } else {
+ result = isc_file_splitpath(mctx, argv[isc_commandline_index],
+ &dir, &filename);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot process filename %s: %s",
+ argv[isc_commandline_index],
+ isc_result_totext(result));
+ if (strcmp(dir, ".") == 0) {
+ isc_mem_free(mctx, dir);
+ dir = NULL;
+ }
+ }
+
+ 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_init2(mctx, ectx, engine,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ if (result != ISC_R_SUCCESS)
+ fatal("Could not initialize dst: %s",
+ isc_result_totext(result));
+ isc_entropy_stopcallbacksources(ectx);
+
+ result = dst_key_fromnamedfile(filename, dir,
+ DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
+ mctx, &key);
+ if (result != ISC_R_SUCCESS)
+ fatal("Invalid keyfile name %s: %s",
+ filename, isc_result_totext(result));
+
+ dst_key_format(key, keystr, sizeof(keystr));
+
+ if (verbose > 2)
+ fprintf(stderr, "%s: %s\n", program, keystr);
+
+ if (force)
+ set_keyversion(key);
+ else
+ check_keyversion(key, keystr);
+
+
+ flags = dst_key_flags(key);
+ if ((flags & DNS_KEYFLAG_REVOKE) == 0) {
+ isc_stdtime_t now;
+
+ if ((flags & DNS_KEYFLAG_KSK) == 0)
+ fprintf(stderr, "%s: warning: Key is not flagged "
+ "as a KSK. Revoking a ZSK is "
+ "legal, but undefined.\n",
+ program);
+
+ isc_stdtime_get(&now);
+ dst_key_settime(key, DST_TIME_REVOKE, now);
+
+ dst_key_setflags(key, flags | DNS_KEYFLAG_REVOKE);
+
+ isc_buffer_init(&buf, newname, sizeof(newname));
+ dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf);
+
+ if (access(newname, F_OK) == 0 && !force) {
+ fatal("Key file %s already exists; "
+ "use -f to force overwrite", newname);
+ }
+
+ result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
+ dir);
+ if (result != ISC_R_SUCCESS) {
+ dst_key_format(key, keystr, sizeof(keystr));
+ fatal("Failed to write key %s: %s", keystr,
+ isc_result_totext(result));
+ }
+
+ isc_buffer_clear(&buf);
+ dst_key_buildfilename(key, 0, dir, &buf);
+ printf("%s\n", newname);
+
+ /*
+ * Remove old key file, if told to (and if
+ * it isn't the same as the new file)
+ */
+ if (remove && dst_key_alg(key) != DST_ALG_RSAMD5) {
+ isc_buffer_init(&buf, oldname, sizeof(oldname));
+ dst_key_setflags(key, flags & ~DNS_KEYFLAG_REVOKE);
+ dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf);
+ if (strcmp(oldname, newname) == 0)
+ goto cleanup;
+ if (access(oldname, F_OK) == 0)
+ unlink(oldname);
+ isc_buffer_clear(&buf);
+ dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf);
+ if (access(oldname, F_OK) == 0)
+ unlink(oldname);
+ }
+ } else {
+ dst_key_format(key, keystr, sizeof(keystr));
+ fatal("Key %s is already revoked", keystr);
+ }
+
+cleanup:
+ dst_key_free(&key);
+ dst_lib_destroy();
+ isc_hash_destroy();
+ cleanup_entropy(&ectx);
+ if (verbose > 10)
+ isc_mem_stats(mctx, stdout);
+ if (dir != NULL)
+ isc_mem_free(mctx, dir);
+ isc_mem_destroy(&mctx);
+
+ return (0);
+}
diff --git a/contrib/bind9/bin/dnssec/dnssec-revoke.docbook b/contrib/bind9/bin/dnssec/dnssec-revoke.docbook
new file mode 100644
index 0000000..b7b5620
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-revoke.docbook
@@ -0,0 +1,149 @@
+<!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) 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-revoke.docbook,v 1.7 2009-11-03 21:44:46 each Exp $ -->
+<refentry id="man.dnssec-revoke">
+ <refentryinfo>
+ <date>June 1, 2009</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>dnssec-revoke</application></refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>dnssec-revoke</application></refname>
+ <refpurpose>Set the REVOKED bit on a DNSSEC key</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2009</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>dnssec-revoke</command>
+ <arg><option>-hr</option></arg>
+ <arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
+ <arg><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
+ <arg><option>-f</option></arg>
+ <arg choice="req">keyfile</arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para><command>dnssec-revoke</command>
+ reads a DNSSEC key file, sets the REVOKED bit on the key as defined
+ in RFC 5011, and creates a new pair of key files containing the
+ now-revoked key.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-h</term>
+ <listitem>
+ <para>
+ Emit usage message and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ Sets the directory in which the key files are to reside.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-r</term>
+ <listitem>
+ <para>
+ After writing the new keyset files remove the original keyset
+ files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-v <replaceable class="parameter">level</replaceable></term>
+ <listitem>
+ <para>
+ Sets the debugging level.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-E <replaceable class="parameter">engine</replaceable></term>
+ <listitem>
+ <para>
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-f</term>
+ <listitem>
+ <para>
+ Force overwrite: Causes <command>dnssec-revoke</command> to
+ write the new key pair even if a file already exists matching
+ the algorithm and key ID of the revoked key.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para><citerefentry>
+ <refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citetitle>BIND 9 Administrator Reference Manual</citetitle>,
+ <citetitle>RFC 5011</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-revoke.html b/contrib/bind9/bin/dnssec/dnssec-revoke.html
new file mode 100644
index 0000000..fad9ac5
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-revoke.html
@@ -0,0 +1,87 @@
+<!--
+ - Copyright (C) 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-revoke.html,v 1.9 2010-05-19 01:14:14 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>dnssec-revoke</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-revoke"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">dnssec-revoke</span> &#8212; Set the REVOKED bit on a DNSSEC key</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">dnssec-revoke</code> [<code class="option">-hr</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-f</code>] {keyfile}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543373"></a><h2>DESCRIPTION</h2>
+<p><span><strong class="command">dnssec-revoke</strong></span>
+ reads a DNSSEC key file, sets the REVOKED bit on the key as defined
+ in RFC 5011, and creates a new pair of key files containing the
+ now-revoked key.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543385"></a><h2>OPTIONS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-h</span></dt>
+<dd><p>
+ Emit usage message and exit.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to reside.
+ </p></dd>
+<dt><span class="term">-r</span></dt>
+<dd><p>
+ After writing the new keyset files remove the original keyset
+ files.
+ </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">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </p></dd>
+<dt><span class="term">-f</span></dt>
+<dd><p>
+ Force overwrite: Causes <span><strong class="command">dnssec-revoke</strong></span> to
+ write the new key pair even if a file already exists matching
+ the algorithm and key ID of the revoked key.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543491"></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 5011</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543515"></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-settime.8 b/contrib/bind9/bin/dnssec/dnssec-settime.8
new file mode 100644
index 0000000..4390494
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-settime.8
@@ -0,0 +1,166 @@
+.\" Copyright (C) 2009, 2010 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-settime.8,v 1.14 2010-08-17 01:15:26 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: dnssec\-settime
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: July 15, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "DNSSEC\-SETTIME" "8" "July 15, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+dnssec\-settime \- Set the key timing metadata for a DNSSEC key
+.SH "SYNOPSIS"
+.HP 15
+\fBdnssec\-settime\fR [\fB\-f\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-h\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] {keyfile}
+.SH "DESCRIPTION"
+.PP
+\fBdnssec\-settime\fR
+reads a DNSSEC private key file and sets the key timing metadata as specified by the
+\fB\-P\fR,
+\fB\-A\fR,
+\fB\-R\fR,
+\fB\-I\fR, and
+\fB\-D\fR
+options. The metadata can then be used by
+\fBdnssec\-signzone\fR
+or other signing software to determine when a key is to be published, whether it should be used for signing a zone, etc.
+.PP
+If none of these options is set on the command line, then
+\fBdnssec\-settime\fR
+simply prints the key timing metadata already stored in the key.
+.PP
+When key metadata fields are changed, both files of a key pair (\fIKnnnn.+aaa+iiiii.key\fR
+and
+\fIKnnnn.+aaa+iiiii.private\fR) are regenerated. Metadata fields are stored in the private file. A human\-readable description of the metadata is also placed in comments in the key file.
+.SH "OPTIONS"
+.PP
+\-f
+.RS 4
+Force an update of an old\-format key with no metadata fields. Without this option,
+\fBdnssec\-settime\fR
+will fail when attempting to update a legacy key. With this option, the key will be recreated in the new format, but with the original key data retained. The key's creation date will be set to the present time.
+.RE
+.PP
+\-K \fIdirectory\fR
+.RS 4
+Sets the directory in which the key files are to reside.
+.RE
+.PP
+\-h
+.RS 4
+Emit usage message and exit.
+.RE
+.PP
+\-v \fIlevel\fR
+.RS 4
+Sets the debugging level.
+.RE
+.PP
+\-E \fIengine\fR
+.RS 4
+Use the given OpenSSL engine. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine.
+.RE
+.SH "TIMING OPTIONS"
+.PP
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To unset a date, use 'none'.
+.PP
+\-P \fIdate/offset\fR
+.RS 4
+Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it.
+.RE
+.PP
+\-A \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it.
+.RE
+.PP
+\-R \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.
+.RE
+.PP
+\-I \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.
+.RE
+.PP
+\-D \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)
+.RE
+.PP
+\-S \fIpredecessor key\fR
+.RS 4
+Select a key for which the key being modified will be an explicit successor. The name, algorithm, size, and type of the predecessor key must exactly match those of the key being modified. The activation date of the successor key will be set to the inactivation date of the predecessor. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.
+.RE
+.PP
+\-i \fIinterval\fR
+.RS 4
+Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.
+.sp
+If the key is being set to be an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.
+.sp
+As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.
+.RE
+.SH "PRINTING OPTIONS"
+.PP
+\fBdnssec\-settime\fR
+can also be used to print the timing metadata associated with a key.
+.PP
+\-u
+.RS 4
+Print times in UNIX epoch format.
+.RE
+.PP
+\-p \fIC/P/A/R/I/D/all\fR
+.RS 4
+Print a specific metadata value or set of metadata values. The
+\fB\-p\fR
+option may be followed by one or more of the following letters to indicate which value or values to print:
+\fBC\fR
+for the creation date,
+\fBP\fR
+for the publication date,
+\fBA\fR
+for the activation date,
+\fBR\fR
+for the revocation date,
+\fBI\fR
+for the inactivation date, or
+\fBD\fR
+for the deletion date. To print all of the metadata, use
+\fB\-p all\fR.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBdnssec\-keygen\fR(8),
+\fBdnssec\-signzone\fR(8),
+BIND 9 Administrator Reference Manual,
+RFC 5011.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/contrib/bind9/bin/dnssec/dnssec-settime.c b/contrib/bind9/bin/dnssec/dnssec-settime.c
new file mode 100644
index 0000000..364e2ab
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-settime.c
@@ -0,0 +1,576 @@
+/*
+ * Copyright (C) 2009, 2010 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-settime.c,v 1.28 2010-12-19 07:29:36 each Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <libgen.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+
+#include <isc/buffer.h>
+#include <isc/commandline.h>
+#include <isc/entropy.h>
+#include <isc/file.h>
+#include <isc/hash.h>
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/keyvalues.h>
+#include <dns/result.h>
+
+#include <dst/dst.h>
+
+#include "dnssectool.h"
+
+const char *program = "dnssec-settime";
+int verbose;
+
+static isc_mem_t *mctx = NULL;
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s [options] keyfile\n\n", program);
+ fprintf(stderr, "Version: %s\n", VERSION);
+ fprintf(stderr, "General options:\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, " -E engine: specify OpenSSL engine "
+ "(default \"pkcs11\")\n");
+#else
+ fprintf(stderr, " -E engine: specify OpenSSL engine\n");
+#endif
+ fprintf(stderr, " -f: force update of old-style "
+ "keys\n");
+ fprintf(stderr, " -K directory: set key file location\n");
+ fprintf(stderr, " -v level: set level of verbosity\n");
+ fprintf(stderr, " -h: help\n");
+ fprintf(stderr, "Timing options:\n");
+ fprintf(stderr, " -P date/[+-]offset/none: set/unset key "
+ "publication date\n");
+ fprintf(stderr, " -A date/[+-]offset/none: set/unset key "
+ "activation date\n");
+ fprintf(stderr, " -R date/[+-]offset/none: set/unset key "
+ "revocation date\n");
+ fprintf(stderr, " -I date/[+-]offset/none: set/unset key "
+ "inactivation date\n");
+ fprintf(stderr, " -D date/[+-]offset/none: set/unset key "
+ "deletion date\n");
+ fprintf(stderr, "Printing options:\n");
+ fprintf(stderr, " -p C/P/A/R/I/D/all: print a particular time "
+ "value or values "
+ "[default: all]\n");
+ fprintf(stderr, " -u: print times in unix epoch "
+ "format\n");
+ fprintf(stderr, "Output:\n");
+ fprintf(stderr, " K<name>+<alg>+<new id>.key, "
+ "K<name>+<alg>+<new id>.private\n");
+
+ exit (-1);
+}
+
+static void
+printtime(dst_key_t *key, int type, const char *tag, isc_boolean_t epoch,
+ FILE *stream)
+{
+ isc_result_t result;
+ const char *output = NULL;
+ isc_stdtime_t when;
+
+ if (tag != NULL)
+ fprintf(stream, "%s: ", tag);
+
+ result = dst_key_gettime(key, type, &when);
+ if (result == ISC_R_NOTFOUND) {
+ fprintf(stream, "UNSET\n");
+ } else if (epoch) {
+ fprintf(stream, "%d\n", (int) when);
+ } else {
+ time_t time = when;
+ output = ctime(&time);
+ fprintf(stream, "%s", output);
+ }
+}
+
+int
+main(int argc, char **argv) {
+ isc_result_t result;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
+ char *filename = NULL, *directory = NULL;
+ char newname[1024];
+ char keystr[DST_KEY_FORMATSIZE];
+ char *endp, *p;
+ int ch;
+ isc_entropy_t *ectx = NULL;
+ const char *predecessor = NULL;
+ dst_key_t *prevkey = NULL;
+ dst_key_t *key = NULL;
+ isc_buffer_t buf;
+ dns_name_t *name = NULL;
+ dns_secalg_t alg = 0;
+ unsigned int size = 0;
+ isc_uint16_t flags = 0;
+ int prepub = -1;
+ isc_stdtime_t now;
+ isc_stdtime_t pub = 0, act = 0, rev = 0, inact = 0, del = 0;
+ isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
+ isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE;
+ isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
+ isc_boolean_t printcreate = ISC_FALSE, printpub = ISC_FALSE;
+ isc_boolean_t printact = ISC_FALSE, printrev = ISC_FALSE;
+ isc_boolean_t printinact = ISC_FALSE, printdel = ISC_FALSE;
+ isc_boolean_t force = ISC_FALSE;
+ isc_boolean_t epoch = ISC_FALSE;
+ isc_boolean_t changed = ISC_FALSE;
+
+ 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;
+
+ isc_stdtime_get(&now);
+
+#define CMDLINE_FLAGS "A:D:E:fhI:i:K:P:p:R:S:uv:"
+ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
+ switch (ch) {
+ case 'E':
+ engine = isc_commandline_argument;
+ break;
+ case 'f':
+ force = ISC_TRUE;
+ break;
+ case 'p':
+ p = isc_commandline_argument;
+ if (!strcasecmp(p, "all")) {
+ printcreate = ISC_TRUE;
+ printpub = ISC_TRUE;
+ printact = ISC_TRUE;
+ printrev = ISC_TRUE;
+ printinact = ISC_TRUE;
+ printdel = ISC_TRUE;
+ break;
+ }
+
+ do {
+ switch (*p++) {
+ case 'C':
+ printcreate = ISC_TRUE;
+ break;
+ case 'P':
+ printpub = ISC_TRUE;
+ break;
+ case 'A':
+ printact = ISC_TRUE;
+ break;
+ case 'R':
+ printrev = ISC_TRUE;
+ break;
+ case 'I':
+ printinact = ISC_TRUE;
+ break;
+ case 'D':
+ printdel = ISC_TRUE;
+ break;
+ case ' ':
+ break;
+ default:
+ usage();
+ break;
+ }
+ } while (*p != '\0');
+ break;
+ case 'u':
+ epoch = ISC_TRUE;
+ break;
+ case 'K':
+ /*
+ * We don't have to copy it here, but do it to
+ * simplify cleanup later
+ */
+ directory = isc_mem_strdup(mctx,
+ isc_commandline_argument);
+ if (directory == NULL) {
+ fatal("Failed to allocate memory for "
+ "directory");
+ }
+ break;
+ case 'v':
+ verbose = strtol(isc_commandline_argument, &endp, 0);
+ if (*endp != '\0')
+ fatal("-v must be followed by a number");
+ break;
+ case 'P':
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetpub = ISC_TRUE;
+ } else {
+ setpub = ISC_TRUE;
+ pub = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'A':
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetact = ISC_TRUE;
+ } else {
+ setact = ISC_TRUE;
+ act = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'R':
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetrev = ISC_TRUE;
+ } else {
+ setrev = ISC_TRUE;
+ rev = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'I':
+ if (setinact || unsetinact)
+ fatal("-I specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetinact = ISC_TRUE;
+ } else {
+ setinact = ISC_TRUE;
+ inact = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'D':
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetdel = ISC_TRUE;
+ } else {
+ setdel = ISC_TRUE;
+ del = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'S':
+ predecessor = isc_commandline_argument;
+ break;
+ case 'i':
+ prepub = strtottl(isc_commandline_argument);
+ 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 (argc < isc_commandline_index + 1 ||
+ argv[isc_commandline_index] == NULL)
+ 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_init2(mctx, ectx, engine,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ if (result != ISC_R_SUCCESS)
+ fatal("Could not initialize dst: %s",
+ isc_result_totext(result));
+ isc_entropy_stopcallbacksources(ectx);
+
+ if (predecessor != NULL) {
+ char keystr[DST_KEY_FORMATSIZE];
+ isc_stdtime_t when;
+ int major, minor;
+
+ if (prepub == -1)
+ prepub = (30 * 86400);
+
+ if (setpub || unsetpub)
+ fatal("-S and -P cannot be used together");
+ if (setact || unsetact)
+ fatal("-S and -A cannot be used together");
+
+ result = dst_key_fromnamedfile(predecessor, directory,
+ DST_TYPE_PUBLIC |
+ DST_TYPE_PRIVATE,
+ mctx, &prevkey);
+ if (result != ISC_R_SUCCESS)
+ fatal("Invalid keyfile %s: %s",
+ filename, isc_result_totext(result));
+ if (!dst_key_isprivate(prevkey))
+ fatal("%s is not a private key", filename);
+
+ name = dst_key_name(prevkey);
+ alg = dst_key_alg(prevkey);
+ size = dst_key_size(prevkey);
+ flags = dst_key_flags(prevkey);
+
+ dst_key_format(prevkey, keystr, sizeof(keystr));
+ dst_key_getprivateformat(prevkey, &major, &minor);
+ if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION)
+ fatal("Predecessor has incompatible format "
+ "version %d.%d\n\t", major, minor);
+
+ result = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when);
+ if (result != ISC_R_SUCCESS)
+ fatal("Predecessor has no activation date. "
+ "You must set one before\n\t"
+ "generating a successor.");
+
+ result = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &act);
+ if (result != ISC_R_SUCCESS)
+ fatal("Predecessor has no inactivation date. "
+ "You must set one before\n\t"
+ "generating a successor.");
+
+ pub = act - prepub;
+ if (pub < now && prepub != 0)
+ fatal("Predecessor will become inactive before the\n\t"
+ "prepublication period ends. Either change "
+ "its inactivation date,\n\t"
+ "or use the -i option to set a shorter "
+ "prepublication interval.");
+
+ result = dst_key_gettime(prevkey, DST_TIME_DELETE, &when);
+ if (result != ISC_R_SUCCESS)
+ fprintf(stderr, "%s: WARNING: Predecessor has no "
+ "removal date;\n\t"
+ "it will remain in the zone "
+ "indefinitely after rollover.\n",
+ program);
+
+ changed = setpub = setact = ISC_TRUE;
+ dst_key_free(&prevkey);
+ } else {
+ if (prepub < 0)
+ prepub = 0;
+
+ if (prepub > 0) {
+ if (setpub && setact && (act - prepub) < pub)
+ fatal("Activation and publication dates "
+ "are closer together than the\n\t"
+ "prepublication interval.");
+
+ if (setpub && !setact) {
+ setact = ISC_TRUE;
+ act = pub + prepub;
+ } else if (setact && !setpub) {
+ setpub = ISC_TRUE;
+ pub = act - prepub;
+ }
+
+ if ((act - prepub) < now)
+ fatal("Time until activation is shorter "
+ "than the\n\tprepublication interval.");
+ }
+ }
+
+ if (directory != NULL) {
+ filename = argv[isc_commandline_index];
+ } else {
+ result = isc_file_splitpath(mctx, argv[isc_commandline_index],
+ &directory, &filename);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot process filename %s: %s",
+ argv[isc_commandline_index],
+ isc_result_totext(result));
+ }
+
+ result = dst_key_fromnamedfile(filename, directory,
+ DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
+ mctx, &key);
+ if (result != ISC_R_SUCCESS)
+ fatal("Invalid keyfile %s: %s",
+ filename, isc_result_totext(result));
+
+ if (!dst_key_isprivate(key))
+ fatal("%s is not a private key", filename);
+
+ dst_key_format(key, keystr, sizeof(keystr));
+
+ if (predecessor != NULL) {
+ if (!dns_name_equal(name, dst_key_name(key)))
+ fatal("Key name mismatch");
+ if (alg != dst_key_alg(key))
+ fatal("Key algorithm mismatch");
+ if (size != dst_key_size(key))
+ fatal("Key size mismatch");
+ if (flags != dst_key_flags(key))
+ fatal("Key flags mismatch");
+ }
+
+ if (force)
+ set_keyversion(key);
+ else
+ check_keyversion(key, keystr);
+
+ if (verbose > 2)
+ fprintf(stderr, "%s: %s\n", program, keystr);
+
+ /*
+ * Set time values.
+ */
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, pub);
+ else if (unsetpub)
+ dst_key_unsettime(key, DST_TIME_PUBLISH);
+
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, act);
+ else if (unsetact)
+ dst_key_unsettime(key, DST_TIME_ACTIVATE);
+
+ if (setrev) {
+ if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0)
+ fprintf(stderr, "%s: warning: Key %s is already "
+ "revoked; changing the revocation date "
+ "will not affect this.\n",
+ program, keystr);
+ if ((dst_key_flags(key) & DNS_KEYFLAG_KSK) == 0)
+ fprintf(stderr, "%s: warning: Key %s is not flagged as "
+ "a KSK, but -R was used. Revoking a "
+ "ZSK is legal, but undefined.\n",
+ program, keystr);
+ dst_key_settime(key, DST_TIME_REVOKE, rev);
+ } else if (unsetrev) {
+ if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0)
+ fprintf(stderr, "%s: warning: Key %s is already "
+ "revoked; removing the revocation date "
+ "will not affect this.\n",
+ program, keystr);
+ dst_key_unsettime(key, DST_TIME_REVOKE);
+ }
+
+ if (setinact)
+ dst_key_settime(key, DST_TIME_INACTIVE, inact);
+ else if (unsetinact)
+ dst_key_unsettime(key, DST_TIME_INACTIVE);
+
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE, del);
+ else if (unsetdel)
+ dst_key_unsettime(key, DST_TIME_DELETE);
+
+ /*
+ * Print out time values, if -p was used.
+ */
+ if (printcreate)
+ printtime(key, DST_TIME_CREATED, "Created", epoch, stdout);
+
+ if (printpub)
+ printtime(key, DST_TIME_PUBLISH, "Publish", epoch, stdout);
+
+ if (printact)
+ printtime(key, DST_TIME_ACTIVATE, "Activate", epoch, stdout);
+
+ if (printrev)
+ printtime(key, DST_TIME_REVOKE, "Revoke", epoch, stdout);
+
+ if (printinact)
+ printtime(key, DST_TIME_INACTIVE, "Inactive", epoch, stdout);
+
+ if (printdel)
+ printtime(key, DST_TIME_DELETE, "Delete", epoch, stdout);
+
+ if (changed) {
+ isc_buffer_init(&buf, newname, sizeof(newname));
+ result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory,
+ &buf);
+ if (result != ISC_R_SUCCESS) {
+ fatal("Failed to build public key filename: %s",
+ isc_result_totext(result));
+ }
+
+ result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
+ directory);
+ if (result != ISC_R_SUCCESS) {
+ dst_key_format(key, keystr, sizeof(keystr));
+ fatal("Failed to write key %s: %s", keystr,
+ isc_result_totext(result));
+ }
+
+ printf("%s\n", newname);
+
+ isc_buffer_clear(&buf);
+ result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory,
+ &buf);
+ if (result != ISC_R_SUCCESS) {
+ fatal("Failed to build private key filename: %s",
+ isc_result_totext(result));
+ }
+ printf("%s\n", newname);
+ }
+
+ dst_key_free(&key);
+ dst_lib_destroy();
+ isc_hash_destroy();
+ cleanup_entropy(&ectx);
+ if (verbose > 10)
+ isc_mem_stats(mctx, stdout);
+ isc_mem_free(mctx, directory);
+ isc_mem_destroy(&mctx);
+
+ return (0);
+}
diff --git a/contrib/bind9/bin/dnssec/dnssec-settime.docbook b/contrib/bind9/bin/dnssec/dnssec-settime.docbook
new file mode 100644
index 0000000..1096cb7
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-settime.docbook
@@ -0,0 +1,319 @@
+<!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) 2009, 2010 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-settime.docbook,v 1.11 2010-08-16 22:21:06 marka Exp $ -->
+<refentry id="man.dnssec-settime">
+ <refentryinfo>
+ <date>July 15, 2009</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>dnssec-settime</application></refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>dnssec-settime</application></refname>
+ <refpurpose>Set the key timing metadata for a DNSSEC key</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2009</year>
+ <year>2010</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>dnssec-settime</command>
+ <arg><option>-f</option></arg>
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
+ <arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-A <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-R <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-I <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-h</option></arg>
+ <arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
+ <arg choice="req">keyfile</arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para><command>dnssec-settime</command>
+ reads a DNSSEC private key file and sets the key timing metadata
+ as specified by the <option>-P</option>, <option>-A</option>,
+ <option>-R</option>, <option>-I</option>, and <option>-D</option>
+ options. The metadata can then be used by
+ <command>dnssec-signzone</command> or other signing software to
+ determine when a key is to be published, whether it should be
+ used for signing a zone, etc.
+ </para>
+ <para>
+ If none of these options is set on the command line,
+ then <command>dnssec-settime</command> simply prints the key timing
+ metadata already stored in the key.
+ </para>
+ <para>
+ When key metadata fields are changed, both files of a key
+ pair (<filename>Knnnn.+aaa+iiiii.key</filename> and
+ <filename>Knnnn.+aaa+iiiii.private</filename>) are regenerated.
+ Metadata fields are stored in the private file. A human-readable
+ description of the metadata is also placed in comments in the key
+ file.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-f</term>
+ <listitem>
+ <para>
+ Force an update of an old-format key with no metadata fields.
+ Without this option, <command>dnssec-settime</command> will
+ fail when attempting to update a legacy key. With this option,
+ the key will be recreated in the new format, but with the
+ original key data retained. The key's creation date will be
+ set to the present time.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ Sets the directory in which the key files are to reside.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-h</term>
+ <listitem>
+ <para>
+ Emit usage message and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-v <replaceable class="parameter">level</replaceable></term>
+ <listitem>
+ <para>
+ Sets the debugging level.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-E <replaceable class="parameter">engine</replaceable></term>
+ <listitem>
+ <para>
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>TIMING OPTIONS</title>
+ <para>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds. To unset a date, use 'none'.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-P <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-A <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-R <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-I <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-D <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-S <replaceable class="parameter">predecessor key</replaceable></term>
+ <listitem>
+ <para>
+ Select a key for which the key being modified will be an
+ explicit successor. The name, algorithm, size, and type of the
+ predecessor key must exactly match those of the key being
+ modified. The activation date of the successor key will be set
+ to the inactivation date of the predecessor. The publication
+ date will be set to the activation date minus the prepublication
+ interval, which defaults to 30 days.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-i <replaceable class="parameter">interval</replaceable></term>
+ <listitem>
+ <para>
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+ </para>
+ <para>
+ If the key is being set to be an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+ </para>
+ <para>
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>PRINTING OPTIONS</title>
+ <para>
+ <command>dnssec-settime</command> can also be used to print the
+ timing metadata associated with a key.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-u</term>
+ <listitem>
+ <para>
+ Print times in UNIX epoch format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-p <replaceable class="parameter">C/P/A/R/I/D/all</replaceable></term>
+ <listitem>
+ <para>
+ Print a specific metadata value or set of metadata values.
+ The <option>-p</option> option may be followed by one or more
+ of the following letters to indicate which value or values to print:
+ <option>C</option> for the creation date,
+ <option>P</option> for the publication date,
+ <option>A</option> for the activation date,
+ <option>R</option> for the revocation date,
+ <option>I</option> for the inactivation date, or
+ <option>D</option> for the deletion date.
+ To print all of the metadata, use <option>-p all</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </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 5011</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-settime.html b/contrib/bind9/bin/dnssec/dnssec-settime.html
new file mode 100644
index 0000000..84c8dde
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-settime.html
@@ -0,0 +1,208 @@
+<!--
+ - Copyright (C) 2009, 2010 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-settime.html,v 1.14 2010-08-17 01:15:26 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>dnssec-settime</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-settime"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">dnssec-settime</span> &#8212; Set the key timing metadata for a DNSSEC key</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">dnssec-settime</code> [<code class="option">-f</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-I <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-h</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] {keyfile}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543419"></a><h2>DESCRIPTION</h2>
+<p><span><strong class="command">dnssec-settime</strong></span>
+ reads a DNSSEC private key file and sets the key timing metadata
+ as specified by the <code class="option">-P</code>, <code class="option">-A</code>,
+ <code class="option">-R</code>, <code class="option">-I</code>, and <code class="option">-D</code>
+ options. The metadata can then be used by
+ <span><strong class="command">dnssec-signzone</strong></span> or other signing software to
+ determine when a key is to be published, whether it should be
+ used for signing a zone, etc.
+ </p>
+<p>
+ If none of these options is set on the command line,
+ then <span><strong class="command">dnssec-settime</strong></span> simply prints the key timing
+ metadata already stored in the key.
+ </p>
+<p>
+ When key metadata fields are changed, both files of a key
+ pair (<code class="filename">Knnnn.+aaa+iiiii.key</code> and
+ <code class="filename">Knnnn.+aaa+iiiii.private</code>) are regenerated.
+ Metadata fields are stored in the private file. A human-readable
+ description of the metadata is also placed in comments in the key
+ file.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543467"></a><h2>OPTIONS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-f</span></dt>
+<dd><p>
+ Force an update of an old-format key with no metadata fields.
+ Without this option, <span><strong class="command">dnssec-settime</strong></span> will
+ fail when attempting to update a legacy key. With this option,
+ the key will be recreated in the new format, but with the
+ original key data retained. The key's creation date will be
+ set to the present time.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to reside.
+ </p></dd>
+<dt><span class="term">-h</span></dt>
+<dd><p>
+ Emit usage message and exit.
+ </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">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543559"></a><h2>TIMING OPTIONS</h2>
+<p>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds. To unset a date, use 'none'.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it.
+ </p></dd>
+<dt><span class="term">-A <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it.
+ </p></dd>
+<dt><span class="term">-R <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </p></dd>
+<dt><span class="term">-I <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </p></dd>
+<dt><span class="term">-D <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </p></dd>
+<dt><span class="term">-S <em class="replaceable"><code>predecessor key</code></em></span></dt>
+<dd><p>
+ Select a key for which the key being modified will be an
+ explicit successor. The name, algorithm, size, and type of the
+ predecessor key must exactly match those of the key being
+ modified. The activation date of the successor key will be set
+ to the inactivation date of the predecessor. The publication
+ date will be set to the activation date minus the prepublication
+ interval, which defaults to 30 days.
+ </p></dd>
+<dt><span class="term">-i <em class="replaceable"><code>interval</code></em></span></dt>
+<dd>
+<p>
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+ </p>
+<p>
+ If the key is being set to be an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+ </p>
+<p>
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+ </p>
+</dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543698"></a><h2>PRINTING OPTIONS</h2>
+<p>
+ <span><strong class="command">dnssec-settime</strong></span> can also be used to print the
+ timing metadata associated with a key.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-u</span></dt>
+<dd><p>
+ Print times in UNIX epoch format.
+ </p></dd>
+<dt><span class="term">-p <em class="replaceable"><code>C/P/A/R/I/D/all</code></em></span></dt>
+<dd><p>
+ Print a specific metadata value or set of metadata values.
+ The <code class="option">-p</code> option may be followed by one or more
+ of the following letters to indicate which value or values to print:
+ <code class="option">C</code> for the creation date,
+ <code class="option">P</code> for the publication date,
+ <code class="option">A</code> for the activation date,
+ <code class="option">R</code> for the revocation date,
+ <code class="option">I</code> for the inactivation date, or
+ <code class="option">D</code> for the deletion date.
+ To print all of the metadata, use <code class="option">-p all</code>.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543912"></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 5011</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543945"></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-signzone.8 b/contrib/bind9/bin/dnssec/dnssec-signzone.8
index bfe7a20..9822883 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.8
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.8
@@ -13,18 +13,18 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-signzone.8,v 1.47.44.8 2009-11-07 01:56:11 tbox Exp $
+.\" $Id: dnssec-signzone.8,v 1.59 2009-12-04 01:13:44 tbox Exp $
.\"
.hy 0
.ad l
.\" Title: dnssec\-signzone
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
-.\" Date: June 08, 2009
+.\" Date: June 05, 2009
.\" Manual: BIND9
.\" Source: BIND9
.\"
-.TH "DNSSEC\-SIGNZONE" "8" "June 08, 2009" "BIND9" "BIND9"
+.TH "DNSSEC\-SIGNZONE" "8" "June 05, 2009" "BIND9" "BIND9"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -33,15 +33,13 @@
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\-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...]
+\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-E\ \fR\fB\fIengine\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\fIdirectory\fR\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\-P\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-T\ \fR\fB\fIttl\fR\fR] [\fB\-t\fR] [\fB\-u\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-x\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
-signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. It also generates a
-\fIkeyset\-\fR
-file containing the key\-signing keys for the zone, and if signing a zone which contains delegations, it can optionally generate DS records for the child zones from their
-\fIkeyset\-\fR
-files.
+signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a
+\fIkeyset\fR
+file for each child zone.
.SH "OPTIONS"
.PP
\-a
@@ -54,30 +52,53 @@ Verify all generated signatures.
Specifies the DNS class of the zone.
.RE
.PP
-\-k \fIkey\fR
-.RS 4
-Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times.
-.RE
-.PP
-\-l \fIdomain\fR
+\-C
.RS 4
-Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records.
+Compatibility mode: Generate a
+\fIkeyset\-\fR\fI\fIzonename\fR\fR
+file in addition to
+\fIdsset\-\fR\fI\fIzonename\fR\fR
+when signing a zone, for use by older versions of
+\fBdnssec\-signzone\fR.
.RE
.PP
\-d \fIdirectory\fR
.RS 4
Look for
-\fIkeyset\fR
+\fIdsset\-\fR
+or
+\fIkeyset\-\fR
files in
-\fBdirectory\fR
-as the directory
+\fBdirectory\fR.
+.RE
+.PP
+\-E \fIengine\fR
+.RS 4
+Uses a crypto hardware (OpenSSL engine) for the crypto operations it supports, for instance signing with private keys from a secure key store. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine.
.RE
.PP
\-g
.RS 4
-If the zone contains any delegations, and there are
+Generate DS records for child zones from
+\fIdsset\-\fR
+or
\fIkeyset\-\fR
-files for any of the child zones, then DS records for the child zones will be generated from the keys in those files. Existing DS records will be removed.
+file. Existing DS records will be removed.
+.RE
+.PP
+\-K \fIdirectory\fR
+.RS 4
+Key repository: Specify a directory to search for DNSSEC keys. If not specified, defaults to the current directory.
+.RE
+.PP
+\-k \fIkey\fR
+.RS 4
+Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times.
+.RE
+.PP
+\-l \fIdomain\fR
+.RS 4
+Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records.
.RE
.PP
\-s \fIstart\-time\fR
@@ -93,6 +114,9 @@ Specify the date and time when the generated RRSIG records expire. As with
\fBstart\-time\fR, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no
\fBend\-time\fR
is specified, 30 days from the start time is used as a default.
+\fBend\-time\fR
+must be later than
+\fBstart\-time\fR.
.RE
.PP
\-f \fIoutput\-file\fR
@@ -208,34 +232,94 @@ specifies the name of a character device or file containing random data to be us
indicates that keyboard input should be used.
.RE
.PP
+\-S
+.RS 4
+Smart signing: Instructs
+\fBdnssec\-signzone\fR
+to search the key repository for keys that match the zone being signed, and to include them in the zone if appropriate.
+.sp
+When a key is found, its timing metadata is examined to determine how it should be used, according to the following rules. Each successive rule takes priority over the prior ones:
+.RS 4
+.PP
+.RS 4
+If no timing metadata has been set for the key, the key is published in the zone and used to sign the zone.
+.RE
+.PP
+.RS 4
+If the key's publication date is set and is in the past, the key is published in the zone.
+.RE
+.PP
+.RS 4
+If the key's activation date is set and in the past, the key is published (regardless of publication date) and used to sign the zone.
+.RE
+.PP
+.RS 4
+If the key's revocation date is set and in the past, and the key is published, then the key is revoked, and the revoked key is used to sign the zone.
+.RE
+.PP
+.RS 4
+If either of the key's unpublication or deletion dates are set and in the past, the key is NOT published or used to sign the zone, regardless of any other metadata.
+.RE
+.RE
+.RE
+.PP
+\-T \fIttl\fR
+.RS 4
+Specifies the TTL to be used for new DNSKEY records imported into the zone from the key repository. If not specified, the default is the minimum TTL value from the zone's SOA record. This option is ignored when signing without
+\fB\-S\fR, since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre\-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match them.
+.RE
+.PP
\-t
.RS 4
Print statistics at completion.
.RE
.PP
+\-u
+.RS 4
+Update NSEC/NSEC3 chain when re\-signing a previously signed zone. With this option, a zone signed with NSEC can be switched to NSEC3, or a zone signed with NSEC3 can be switch to NSEC or to NSEC3 with different parameters. Without this option,
+\fBdnssec\-signzone\fR
+will retain the existing chain when re\-signing.
+.RE
+.PP
\-v \fIlevel\fR
.RS 4
Sets the debugging level.
.RE
.PP
+\-x
+.RS 4
+Only sign the DNSKEY RRset with key\-signing keys, and omit signatures from zone\-signing keys. (This is similar to the
+\fBdnssec\-dnskey\-kskonly yes;\fR
+zone option in
+\fBnamed\fR.)
+.RE
+.PP
\-z
.RS 4
-Ignore KSK flag on key when determining what to sign.
+Ignore KSK flag on key when determining what to sign. This causes KSK\-flagged keys to sign all records, not just the DNSKEY RRset. (This is similar to the
+\fBupdate\-check\-ksk no;\fR
+zone option in
+\fBnamed\fR.)
.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.
+Generate an 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.
+When generating an NSEC3 chain, use this many interations. The default is 10.
.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.
+When generating an NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations.
+.sp
+Using this option twice (i.e.,
+\fB\-AA\fR) turns the OPTOUT flag off for all records. This is useful when using the
+\fB\-u\fR
+option to modify an NSEC3 chain which previously had OPTOUT set.
.RE
.PP
zonefile
@@ -253,9 +337,11 @@ The following command signs the
\fBexample.com\fR
zone with the DSA key generated by
\fBdnssec\-keygen\fR
-(Kexample.com.+003+17247). The zone's keys must be in the master file (\fIdb.example.com\fR). This invocation looks for
-\fIkeyset\fR
-files, in the current directory, so that DS records can be generated from them (\fB\-g\fR).
+(Kexample.com.+003+17247). Because the
+\fB\-S\fR
+option is not being used, the zone's keys must be in the master file (\fIdb.example.com\fR). This invocation looks for
+\fIdsset\fR
+files, in the current directory, so that DS records can be imported from them (\fB\-g\fR).
.sp
.RS 4
.nf
@@ -283,18 +369,6 @@ db.example.com.signed
%
.fi
.RE
-.SH "KNOWN BUGS"
-.PP
-\fBdnssec\-signzone\fR
-was designed so that it could sign a zone partially, using only a subset of the DNSSEC keys needed to produce a fully\-signed zone. This permits a zone administrator, for example, to sign a zone with one key on one machine, move the resulting partially\-signed zone to a second machine, and sign it again with a second key.
-.PP
-An unfortunate side\-effect of this flexibility is that
-\fBdnssec\-signzone\fR
-does not check to make sure it's signing a zone with any valid keys at all. An attempt to sign a zone without any keys will appear to succeed, producing a "signed" zone with no signatures. There is no warning issued when a zone is not fully signed.
-.PP
-This will be corrected in a future release. In the meantime, ISC recommends examining the output of
-\fBdnssec\-signzone\fR
-to confirm that the zone is properly signed by all keys before using it.
.SH "SEE ALSO"
.PP
\fBdnssec\-keygen\fR(8),
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.c b/contrib/bind9/bin/dnssec/dnssec-signzone.c
index b8f4d66..3997a13 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.c
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.c
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-signzone.c,v 1.209.12.20 2010-06-03 23:47:48 tbox Exp $ */
+/* $Id: dnssec-signzone.c,v 1.262 2010-06-03 23:51:04 tbox Exp $ */
/*! \file */
@@ -87,6 +87,10 @@
#include "dnssectool.h"
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* AIX, WIN32, and others don't define this. */
+#endif
+
const char *program = "dnssec-signzone";
int verbose;
@@ -97,22 +101,11 @@ static int nsec_datatype = dns_rdatatype_nsec;
#define IS_NSEC3 (nsec_datatype == dns_rdatatype_nsec3)
#define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
+#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
+
#define BUFSIZE 2048
#define MAXDSKEYS 8
-typedef struct signer_key_struct signer_key_t;
-
-struct signer_key_struct {
- dst_key_t *key;
- isc_boolean_t issigningkey;
- isc_boolean_t isdsk;
- isc_boolean_t isksk;
- isc_boolean_t wasused;
- isc_boolean_t commandline;
- unsigned int position;
- ISC_LINK(signer_key_t) link;
-};
-
#define SIGNER_EVENTCLASS ISC_EVENTCLASS(0x4453)
#define SIGNER_EVENT_WRITE (SIGNER_EVENTCLASS + 0)
#define SIGNER_EVENT_WORK (SIGNER_EVENTCLASS + 1)
@@ -128,7 +121,7 @@ struct signer_event {
dns_dbnode_t *node;
};
-static ISC_LIST(signer_key_t) keylist;
+static dns_dnsseckeylist_t keylist;
static unsigned int keycount = 0;
isc_rwlock_t keylist_lock;
static isc_stdtime_t starttime = 0, endtime = 0, now;
@@ -138,7 +131,8 @@ static isc_boolean_t tryverify = ISC_FALSE;
static isc_boolean_t printstats = ISC_FALSE;
static isc_mem_t *mctx = NULL;
static isc_entropy_t *ectx = NULL;
-static dns_ttl_t zonettl;
+static dns_ttl_t zone_soa_min_ttl;
+static dns_ttl_t soa_ttl;
static FILE *fp;
static char *tempfile = NULL;
static const dns_master_style_t *masterstyle;
@@ -146,7 +140,7 @@ static dns_masterformat_t inputformat = dns_masterformat_text;
static dns_masterformat_t outputformat = dns_masterformat_text;
static unsigned int nsigned = 0, nretained = 0, ndropped = 0;
static unsigned int nverified = 0, nverifyfailed = 0;
-static const char *directory;
+static const char *directory = NULL, *dsdir = NULL;
static isc_mutex_t namelock, statslock;
static isc_taskmgr_t *taskmgr = NULL;
static dns_db_t *gdb; /* The database */
@@ -155,13 +149,18 @@ 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 dns_iterations_t nsec3iter = 10U;
+static unsigned char saltbuf[255];
+static unsigned char *salt = saltbuf;
+static size_t salt_length = 0;
static isc_task_t *master = NULL;
static unsigned int ntasks = 0;
static isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE;
static isc_boolean_t nokeys = ISC_FALSE;
static isc_boolean_t removefile = ISC_FALSE;
static isc_boolean_t generateds = ISC_FALSE;
-static isc_boolean_t ignoreksk = ISC_FALSE;
+static isc_boolean_t ignore_kskflag = ISC_FALSE;
+static isc_boolean_t keyset_kskonly = ISC_FALSE;
static dns_name_t *dlv = NULL;
static dns_fixedname_t dlv_fixed;
static dns_master_style_t *dsstyle = NULL;
@@ -169,6 +168,9 @@ static unsigned int serialformat = SOA_SERIAL_KEEP;
static unsigned int hash_length = 0;
static isc_boolean_t unknownalg = ISC_FALSE;
static isc_boolean_t disable_zone_check = ISC_FALSE;
+static isc_boolean_t update_chain = ISC_FALSE;
+static isc_boolean_t set_keyttl = ISC_FALSE;
+static dns_ttl_t keyttl;
#define INCSTAT(counter) \
if (printstats) { \
@@ -195,48 +197,23 @@ dumpnode(dns_name_t *name, dns_dbnode_t *node) {
check_result(result, "dns_master_dumpnodetostream");
}
-static signer_key_t *
-newkeystruct(dst_key_t *dstkey, isc_boolean_t signwithkey) {
- signer_key_t *key;
-
- key = isc_mem_get(mctx, sizeof(signer_key_t));
- if (key == NULL)
- fatal("out of memory");
- key->key = dstkey;
- if ((dst_key_flags(dstkey) & DNS_KEYFLAG_KSK) != 0) {
- key->issigningkey = signwithkey;
- key->isksk = ISC_TRUE;
- key->isdsk = ISC_FALSE;
- } else {
- key->issigningkey = signwithkey;
- key->isksk = ISC_FALSE;
- key->isdsk = ISC_TRUE;
- }
- key->wasused = ISC_FALSE;
- key->commandline = ISC_FALSE;
- key->position = keycount++;
- ISC_LINK_INIT(key, link);
- return (key);
-}
-
/*%
* Sign the given RRset with given key, and add the signature record to the
* given tuple.
*/
-
static void
signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
dns_ttl_t ttl, dns_diff_t *add, const char *logmsg)
{
isc_result_t result;
isc_stdtime_t jendtime;
- char keystr[KEY_FORMATSIZE];
+ char keystr[DST_KEY_FORMATSIZE];
dns_rdata_t trdata = DNS_RDATA_INIT;
unsigned char array[BUFSIZE];
isc_buffer_t b;
dns_difftuple_t *tuple;
- key_format(key, keystr, sizeof(keystr));
+ dst_key_format(key, keystr, sizeof(keystr));
vbprintf(1, "\t%s %s\n", logmsg, keystr);
jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime;
@@ -245,8 +222,8 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
mctx, &b, &trdata);
isc_entropy_stopcallbacksources(ectx);
if (result != ISC_R_SUCCESS) {
- char keystr[KEY_FORMATSIZE];
- key_format(key, keystr, sizeof(keystr));
+ char keystr[DST_KEY_FORMATSIZE];
+ dst_key_format(key, keystr, sizeof(keystr));
fatal("dnskey '%s' failed to sign data: %s",
keystr, isc_result_totext(result));
}
@@ -272,31 +249,43 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
}
static inline isc_boolean_t
-issigningkey(signer_key_t *key) {
- return (key->issigningkey);
+issigningkey(dns_dnsseckey_t *key) {
+ return (key->force_sign || key->hint_sign);
}
static inline isc_boolean_t
-iszonekey(signer_key_t *key) {
+iszonekey(dns_dnsseckey_t *key) {
return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) &&
dst_key_iszonekey(key->key)));
}
+static inline isc_boolean_t
+isksk(dns_dnsseckey_t *key) {
+ return (key->ksk);
+}
+
+static inline isc_boolean_t
+iszsk(dns_dnsseckey_t *key) {
+ return (ignore_kskflag || !key->ksk);
+}
+
/*%
- * Find the key if it is in our list. If it is, return it, otherwise null.
+ * Find the key that generated an RRSIG, if it is in the key list. If
+ * so, return a pointer to it, otherwise return NULL.
+ *
* No locking is performed here, this must be done by the caller.
*/
-static signer_key_t *
+static dns_dnsseckey_t *
keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
- signer_key_t *key;
+ dns_dnsseckey_t *key;
- key = ISC_LIST_HEAD(keylist);
- while (key != NULL) {
+ for (key = ISC_LIST_HEAD(keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
if (rrsig->keyid == dst_key_id(key->key) &&
rrsig->algorithm == dst_key_alg(key->key) &&
dns_name_equal(&rrsig->signer, dst_key_name(key->key)))
return (key);
- key = ISC_LIST_NEXT(key, link);
}
return (NULL);
}
@@ -305,11 +294,11 @@ keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
* Finds the key that generated a RRSIG, if possible. First look at the keys
* that we've loaded already, and then see if there's a key on disk.
*/
-static signer_key_t *
+static dns_dnsseckey_t *
keythatsigned(dns_rdata_rrsig_t *rrsig) {
isc_result_t result;
dst_key_t *pubkey = NULL, *privkey = NULL;
- signer_key_t *key;
+ dns_dnsseckey_t *key = NULL;
isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read);
key = keythatsigned_unlocked(rrsig);
@@ -325,7 +314,6 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
* after all.
*/
isc_rwlock_lock(&keylist_lock, isc_rwlocktype_write);
-
key = keythatsigned_unlocked(rrsig);
if (key != NULL) {
isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
@@ -334,7 +322,7 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
rrsig->algorithm, DST_TYPE_PUBLIC,
- NULL, mctx, &pubkey);
+ directory, mctx, &pubkey);
if (result != ISC_R_SUCCESS) {
isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
return (NULL);
@@ -343,12 +331,15 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
rrsig->algorithm,
DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
- NULL, mctx, &privkey);
+ directory, mctx, &privkey);
if (result == ISC_R_SUCCESS) {
dst_key_free(&pubkey);
- key = newkeystruct(privkey, ISC_FALSE);
- } else
- key = newkeystruct(pubkey, ISC_FALSE);
+ dns_dnsseckey_create(mctx, &privkey, &key);
+ } else {
+ dns_dnsseckey_create(mctx, &pubkey, &key);
+ }
+ key->force_publish = ISC_TRUE;
+ key->force_sign = ISC_FALSE;
ISC_LIST_APPEND(keylist, key, link);
isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
@@ -383,15 +374,16 @@ expecttofindkey(dns_name_t *name) {
dns_name_format(name, namestr, sizeof(namestr));
fatal("failure looking for '%s DNSKEY' in database: %s",
namestr, isc_result_totext(result));
+ /* NOTREACHED */
return (ISC_FALSE); /* removes a warning */
}
static inline isc_boolean_t
-setverifies(dns_name_t *name, dns_rdataset_t *set, signer_key_t *key,
+setverifies(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
dns_rdata_t *rrsig)
{
isc_result_t result;
- result = dns_dnssec_verify(name, set, key->key, ISC_FALSE, mctx, rrsig);
+ result = dns_dnssec_verify(name, set, key, ISC_FALSE, mctx, rrsig);
if (result == ISC_R_SUCCESS) {
INCSTAT(nverified);
return (ISC_TRUE);
@@ -413,7 +405,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
dns_rdataset_t sigset;
dns_rdata_t sigrdata = DNS_RDATA_INIT;
dns_rdata_rrsig_t rrsig;
- signer_key_t *key;
+ dns_dnsseckey_t *key;
isc_result_t result;
isc_boolean_t nosigs = ISC_FALSE;
isc_boolean_t *wassignedby, *nowsignedby;
@@ -483,8 +475,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
"invalid validity period\n",
sigstr);
} else if (key == NULL && !future &&
- expecttofindkey(&rrsig.signer))
- {
+ expecttofindkey(&rrsig.signer)) {
/* rrsig is dropped and not replaced */
vbprintf(2, "\trrsig by %s dropped - "
"private dnskey not found\n",
@@ -495,35 +486,33 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
if (!expired)
keep = ISC_TRUE;
} else if (issigningkey(key)) {
- if (!expired && setverifies(name, set, key, &sigrdata))
- {
+ if (!expired && setverifies(name, set, key->key,
+ &sigrdata)) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
keep = ISC_TRUE;
- wassignedby[key->position] = ISC_TRUE;
- nowsignedby[key->position] = ISC_TRUE;
- key->wasused = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr,
expired ? "expired" :
"failed to verify");
- wassignedby[key->position] = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
resign = ISC_TRUE;
}
} else if (iszonekey(key)) {
- if (!expired && setverifies(name, set, key, &sigrdata))
- {
+ if (!expired && setverifies(name, set, key->key,
+ &sigrdata)) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
keep = ISC_TRUE;
- wassignedby[key->position] = ISC_TRUE;
- nowsignedby[key->position] = ISC_TRUE;
- key->wasused = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr,
expired ? "expired" :
"failed to verify");
- wassignedby[key->position] = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
}
} else if (!expired) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
@@ -533,7 +522,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
}
if (keep) {
- nowsignedby[key->position] = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
INCSTAT(nretained);
if (sigset.ttl != ttl) {
vbprintf(2, "\tfixing ttl %s\n", sigstr);
@@ -568,8 +557,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
signwithkey(name, set, key->key, ttl, add,
"resigning with dnskey");
- nowsignedby[key->position] = ISC_TRUE;
- key->wasused = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
}
dns_rdata_reset(&sigrdata);
@@ -587,20 +575,37 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
key != NULL;
key = ISC_LIST_NEXT(key, link))
{
- if (nowsignedby[key->position])
+ if (nowsignedby[key->index])
continue;
- if (!key->issigningkey)
- continue;
- if (!(ignoreksk || key->isdsk ||
- (key->isksk &&
- set->type == dns_rdatatype_dnskey &&
- dns_name_equal(name, gorigin))))
+ if (!issigningkey(key))
continue;
- signwithkey(name, set, key->key, ttl, add,
- "signing with dnskey");
- key->wasused = ISC_TRUE;
+ if (set->type == dns_rdatatype_dnskey &&
+ dns_name_equal(name, gorigin)) {
+ isc_boolean_t have_ksk;
+ dns_dnsseckey_t *tmpkey;
+
+ have_ksk = isksk(key);
+ for (tmpkey = ISC_LIST_HEAD(keylist);
+ tmpkey != NULL;
+ tmpkey = ISC_LIST_NEXT(tmpkey, link)) {
+ if (dst_key_alg(key->key) !=
+ dst_key_alg(tmpkey->key))
+ continue;
+ if (REVOKE(tmpkey->key))
+ continue;
+ if (isksk(tmpkey))
+ have_ksk = ISC_TRUE;
+ }
+ if (isksk(key) || !have_ksk ||
+ (iszsk(key) && !keyset_kskonly))
+ signwithkey(name, set, key->key, ttl, add,
+ "signing with dnskey");
+ } else if (iszsk(key)) {
+ signwithkey(name, set, key->key, ttl, add,
+ "signing with dnskey");
+ }
}
isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t));
@@ -774,16 +779,21 @@ static void
opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass,
dns_db_t **dbp)
{
- char filename[256];
+ char filename[PATH_MAX];
isc_buffer_t b;
isc_result_t result;
isc_buffer_init(&b, filename, sizeof(filename));
- if (directory != NULL) {
- isc_buffer_putstr(&b, directory);
- if (directory[strlen(directory) - 1] != '/')
+ if (dsdir != NULL) {
+ /* allow room for a trailing slash */
+ if (strlen(dsdir) >= isc_buffer_availablelength(&b))
+ fatal("path '%s' is too long", dsdir);
+ isc_buffer_putstr(&b, dsdir);
+ if (dsdir[strlen(dsdir) - 1] != '/')
isc_buffer_putstr(&b, "/");
}
+ if (strlen(prefix) > isc_buffer_availablelength(&b))
+ fatal("path '%s' is too long", dsdir);
isc_buffer_putstr(&b, prefix);
result = dns_name_tofilenametext(name, ISC_FALSE, &b);
check_result(result, "dns_name_tofilenametext()");
@@ -798,13 +808,15 @@ opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass,
rdclass, 0, NULL, dbp);
check_result(result, "dns_db_create()");
- result = dns_db_load(*dbp, filename);
+ result = dns_db_load3(*dbp, filename, inputformat, DNS_MASTER_HINT);
if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
dns_db_detach(dbp);
}
/*%
- * Loads the key set for a child zone, if there is one, and builds DS records.
+ * Load the DS set for a child zone, if a dsset-* file can be found.
+ * If not, try to find a keyset-* file from an earlier version of
+ * dnssec-signzone, and build DS records from that.
*/
static isc_result_t
loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
@@ -818,29 +830,49 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
dns_diff_t diff;
dns_difftuple_t *tuple = NULL;
+ opendb("dsset-", name, gclass, &db);
+ if (db != NULL) {
+ result = dns_db_findnode(db, name, ISC_FALSE, &node);
+ if (result == ISC_R_SUCCESS) {
+ dns_rdataset_init(dsset);
+ result = dns_db_findrdataset(db, node, NULL,
+ dns_rdatatype_ds, 0, 0,
+ dsset, NULL);
+ dns_db_detachnode(db, &node);
+ if (result == ISC_R_SUCCESS) {
+ vbprintf(2, "found DS records\n");
+ dsset->ttl = ttl;
+ dns_db_detach(&db);
+ return (result);
+ }
+ }
+ dns_db_detach(&db);
+ }
+
+ /* No DS records found; try again, looking for DNSKEY records */
opendb("keyset-", name, gclass, &db);
- if (db == NULL)
+ if (db == NULL) {
return (ISC_R_NOTFOUND);
+ }
result = dns_db_findnode(db, name, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS) {
dns_db_detach(&db);
- return (DNS_R_BADDB);
+ return (result);
}
+
dns_rdataset_init(&keyset);
- result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0,
- 0, &keyset, NULL);
+ result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0,
+ &keyset, NULL);
if (result != ISC_R_SUCCESS) {
dns_db_detachnode(db, &node);
dns_db_detach(&db);
return (result);
}
-
vbprintf(2, "found DNSKEY records\n");
result = dns_db_newversion(db, &ver);
check_result(result, "dns_db_newversion");
-
dns_diff_init(mctx, &diff);
for (result = dns_rdataset_first(&keyset);
@@ -869,6 +901,7 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
check_result(result, "dns_difftuple_create");
dns_diff_append(&diff, &tuple);
}
+
result = dns_diff_apply(&diff, db, ver);
check_result(result, "dns_diff_apply");
dns_diff_clear(&diff);
@@ -1112,17 +1145,15 @@ active_node(dns_dbnode_t *node) {
}
/*%
- * Extracts the TTL from the SOA.
+ * Extracts the minimum TTL from the SOA record, and the SOA record's TTL.
*/
-static dns_ttl_t
-soattl(void) {
+static void
+get_soa_ttls(void) {
dns_rdataset_t soaset;
dns_fixedname_t fname;
dns_name_t *name;
isc_result_t result;
- dns_ttl_t ttl;
dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_soa_t soa;
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
@@ -1136,11 +1167,9 @@ soattl(void) {
result = dns_rdataset_first(&soaset);
check_result(result, "dns_rdataset_first");
dns_rdataset_current(&soaset, &rdata);
- result = dns_rdata_tostruct(&rdata, &soa, NULL);
- check_result(result, "dns_rdata_tostruct");
- ttl = soa.minimum;
+ zone_soa_min_ttl = dns_soa_getminimum(&rdata);
+ soa_ttl = soaset.ttl;
dns_rdataset_disassociate(&soaset);
- return (ttl);
}
/*%
@@ -1371,7 +1400,7 @@ verifyset(dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node,
for (i = 0; i < 256; i++)
if ((ksk_algorithms[i] != 0) &&
(set_algorithms[i] == 0)) {
- alg_format(i, algbuf, sizeof(algbuf));
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
fprintf(stderr, "Missing %s signature for "
"%s %s\n", algbuf, namebuf, typebuf);
bad_algorithms[i] = 1;
@@ -1414,8 +1443,8 @@ verifynode(dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation,
/*%
* Verify that certain things are sane:
*
- * The apex has a DNSKEY record with at least one KSK and at least
- * one ZSK.
+ * The apex has a DNSKEY record with at least one KSK, and at least
+ * one ZSK if the -x flag was not used.
*
* The DNSKEY record was signed with at least one of the KSKs in this
* set.
@@ -1440,8 +1469,10 @@ verifyzone(void) {
isc_boolean_t goodksk = ISC_FALSE;
isc_boolean_t goodzsk = ISC_FALSE;
isc_result_t result;
- unsigned char revoked[256];
- unsigned char standby[256];
+ unsigned char revoked_ksk[256];
+ unsigned char revoked_zsk[256];
+ unsigned char standby_ksk[256];
+ unsigned char standby_zsk[256];
unsigned char ksk_algorithms[256];
unsigned char zsk_algorithms[256];
unsigned char bad_algorithms[256];
@@ -1470,8 +1501,10 @@ verifyzone(void) {
if (!dns_rdataset_isassociated(&sigrdataset))
fatal("cannot find DNSKEY RRSIGs\n");
- memset(revoked, 0, sizeof(revoked));
- memset(standby, 0, sizeof(revoked));
+ memset(revoked_ksk, 0, sizeof(revoked_ksk));
+ memset(revoked_zsk, 0, sizeof(revoked_zsk));
+ memset(standby_ksk, 0, sizeof(standby_ksk));
+ memset(standby_zsk, 0, sizeof(standby_zsk));
memset(ksk_algorithms, 0, sizeof(ksk_algorithms));
memset(zsk_algorithms, 0, sizeof(zsk_algorithms));
memset(bad_algorithms, 0, sizeof(bad_algorithms));
@@ -1480,8 +1513,9 @@ verifyzone(void) {
#endif
/*
- * Check that the DNSKEY RR has at least one self signing KSK and
- * one ZSK per algorithm in it.
+ * Check that the DNSKEY RR has at least one self signing KSK
+ * and one ZSK per algorithm in it (or, if -x was used, one
+ * self-signing KSK).
*/
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
@@ -1511,8 +1545,11 @@ verifyzone(void) {
(int)isc_buffer_usedlength(&buf), buffer);
}
if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
- revoked[dnskey.algorithm] != 255)
- revoked[dnskey.algorithm]++;
+ revoked_ksk[dnskey.algorithm] != 255)
+ revoked_ksk[dnskey.algorithm]++;
+ else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 &&
+ revoked_zsk[dnskey.algorithm] != 255)
+ revoked_zsk[dnskey.algorithm]++;
} else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
&sigrdataset, ISC_FALSE, mctx)) {
@@ -1520,8 +1557,8 @@ verifyzone(void) {
ksk_algorithms[dnskey.algorithm]++;
goodksk = ISC_TRUE;
} else {
- if (standby[dnskey.algorithm] != 255)
- standby[dnskey.algorithm]++;
+ if (standby_ksk[dnskey.algorithm] != 255)
+ standby_ksk[dnskey.algorithm]++;
}
} else if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
&sigrdataset, ISC_FALSE,
@@ -1534,8 +1571,8 @@ verifyzone(void) {
zsk_algorithms[dnskey.algorithm]++;
goodzsk = ISC_TRUE;
} else {
- if (zsk_algorithms[dnskey.algorithm] != 255)
- zsk_algorithms[dnskey.algorithm]++;
+ if (standby_zsk[dnskey.algorithm] != 255)
+ standby_zsk[dnskey.algorithm]++;
#ifdef ALLOW_KSKLESS_ZONES
allzsksigned = ISC_FALSE;
#endif
@@ -1545,42 +1582,54 @@ verifyzone(void) {
}
dns_rdataset_disassociate(&sigrdataset);
- if (!goodksk) {
#ifdef ALLOW_KSKLESS_ZONES
- if (!goodzsk)
- fatal("no self signing keys found");
- fprintf(stderr, "No self signing KSK found. Using self signed "
- "ZSK's for active algorithm list.\n");
+ if (!goodksk) {
+ if (!ignore_kskflag)
+ fprintf(stderr, "No self signing KSK found. Using "
+ "self signed ZSK's for active "
+ "algorithm list.\n");
memcpy(ksk_algorithms, self_algorithms, sizeof(ksk_algorithms));
if (!allzsksigned)
fprintf(stderr, "warning: not all ZSK's are self "
"signed.\n");
+ }
#else
+ if (!goodksk) {
fatal("no self signed KSK's found");
-#endif
}
+#endif
fprintf(stderr, "Verifying the zone using the following algorithms:");
for (i = 0; i < 256; i++) {
- if (ksk_algorithms[i] != 0) {
- alg_format(i, algbuf, sizeof(algbuf));
+#ifdef ALLOW_KSKLESS_ZONES
+ if (ksk_algorithms[i] != 0 || zsk_algorithms[i] != 0)
+#else
+ if (ksk_algorithms[i] != 0)
+#endif
+ {
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
fprintf(stderr, " %s", algbuf);
}
}
fprintf(stderr, ".\n");
- for (i = 0; i < 256; i++) {
- /*
- * The counts should both be zero or both be non-zero.
- * Mark the algorithm as bad if this is not met.
- */
- if ((ksk_algorithms[i] != 0) == (zsk_algorithms[i] != 0))
- continue;
- alg_format(i, algbuf, sizeof(algbuf));
- fprintf(stderr, "Missing %s for algorithm %s\n",
- (ksk_algorithms[i] != 0) ? "ZSK" : "self signing KSK",
- algbuf);
- bad_algorithms[i] = 1;
+ if (!ignore_kskflag && !keyset_kskonly) {
+ for (i = 0; i < 256; i++) {
+ /*
+ * The counts should both be zero or both be non-zero.
+ * Mark the algorithm as bad if this is not met.
+ */
+ if ((ksk_algorithms[i] != 0) ==
+ (zsk_algorithms[i] != 0))
+ continue;
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Missing %s for algorithm %s\n",
+ (ksk_algorithms[i] != 0)
+ ? "ZSK"
+ : "self signing KSK",
+ algbuf);
+ bad_algorithms[i] = 1;
+ }
}
/*
@@ -1674,7 +1723,7 @@ verifyzone(void) {
if (first)
fprintf(stderr, "The zone is not fully signed "
"for the following algorithms:");
- alg_format(i, algbuf, sizeof(algbuf));
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
fprintf(stderr, " %s", algbuf);
first = ISC_FALSE;
}
@@ -1684,21 +1733,30 @@ verifyzone(void) {
fatal("DNSSEC completeness test failed.");
}
- if (goodksk) {
+ if (goodksk || ignore_kskflag) {
/*
* Print the success summary.
*/
fprintf(stderr, "Zone signing complete:\n");
for (i = 0; i < 256; i++) {
- if ((zsk_algorithms[i] != 0) ||
- (ksk_algorithms[i] != 0) ||
- (revoked[i] != 0) || (standby[i] != 0)) {
- alg_format(i, algbuf, sizeof(algbuf));
- fprintf(stderr, "Algorithm: %s: ZSKs: %u, "
- "KSKs: %u active, %u revoked, %u "
- "stand-by\n", algbuf,
- zsk_algorithms[i], ksk_algorithms[i],
- revoked[i], standby[i]);
+ if ((ksk_algorithms[i] != 0) ||
+ (standby_ksk[i] != 0) ||
+ (revoked_zsk[i] != 0) ||
+ (zsk_algorithms[i] != 0) ||
+ (standby_zsk[i] != 0) ||
+ (revoked_zsk[i] != 0)) {
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Algorithm: %s: KSKs: "
+ "%u active, %u stand-by, %u revoked\n",
+ algbuf, ksk_algorithms[i],
+ standby_ksk[i], revoked_ksk[i]);
+ fprintf(stderr, "%*sZSKs: "
+ "%u active, %u %s, %u revoked\n",
+ (int) strlen(algbuf) + 13, "",
+ zsk_algorithms[i],
+ standby_zsk[i],
+ keyset_kskonly ? "present" : "stand-by",
+ revoked_zsk[i]);
}
}
}
@@ -1923,6 +1981,7 @@ add_ds(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t nsttl) {
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,
@@ -1953,7 +2012,7 @@ remove_records(dns_dbnode_t *node, dns_rdatatype_t which) {
dns_rdataset_init(&rdataset);
/*
- * Delete any NSEC records at the apex.
+ * Delete any records of the given type at the apex.
*/
result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
check_result(result, "dns_db_allrdatasets()");
@@ -1965,6 +2024,12 @@ remove_records(dns_dbnode_t *node, dns_rdatatype_t which) {
covers = rdataset.covers;
dns_rdataset_disassociate(&rdataset);
if (type == which || covers == which) {
+ if (which == dns_rdatatype_nsec && !update_chain)
+ fatal("Zone contains NSEC records. Use -u "
+ "to update to NSEC3.");
+ if (which == dns_rdatatype_nsec3param && !update_chain)
+ fatal("Zone contains NSEC3 chains. Use -u "
+ "to update to NSEC.");
result = dns_db_deleterdataset(gdb, node, gversion,
type, covers);
check_result(result, "dns_db_deleterdataset()");
@@ -2088,8 +2153,9 @@ nsecify(void) {
} else if (result != ISC_R_SUCCESS)
fatal("iterating through the database failed: %s",
isc_result_totext(result));
+ dns_dbiterator_pause(dbiter);
result = dns_nsec_build(gdb, gversion, node, nextname,
- zonettl);
+ zone_soa_min_ttl);
check_result(result, "dns_nsec_build()");
dns_db_detachnode(gdb, &node);
}
@@ -2320,6 +2386,97 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node,
check_result(result, "dns_db_deleterdataset(RRSIG(NSEC3))");
}
+static void
+rrset_remove_duplicates(dns_name_t *name, dns_rdataset_t *rdataset,
+ dns_diff_t *diff)
+{
+ dns_difftuple_t *tuple = NULL;
+ isc_result_t result;
+ unsigned int count1 = 0;
+ dns_rdataset_t tmprdataset;
+
+ dns_rdataset_init(&tmprdataset);
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_t rdata1 = DNS_RDATA_INIT;
+ unsigned int count2 = 0;
+
+ count1++;
+ dns_rdataset_current(rdataset, &rdata1);
+ dns_rdataset_clone(rdataset, &tmprdataset);
+ for (result = dns_rdataset_first(&tmprdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&tmprdataset)) {
+ dns_rdata_t rdata2 = DNS_RDATA_INIT;
+ count2++;
+ if (count1 >= count2)
+ continue;
+ dns_rdataset_current(&tmprdataset, &rdata2);
+ if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
+ result = dns_difftuple_create(mctx,
+ DNS_DIFFOP_DEL,
+ name,
+ rdataset->ttl,
+ &rdata2, &tuple);
+ check_result(result, "dns_difftuple_create");
+ dns_diff_append(diff, &tuple);
+ }
+ }
+ dns_rdataset_disassociate(&tmprdataset);
+ }
+}
+
+static void
+remove_duplicates(void) {
+ isc_result_t result;
+ dns_dbiterator_t *dbiter = NULL;
+ dns_rdatasetiter_t *rdsiter = NULL;
+ dns_diff_t diff;
+ dns_dbnode_t *node = NULL;
+ dns_rdataset_t rdataset;
+ dns_fixedname_t fname;
+ dns_name_t *name;
+
+ dns_diff_init(mctx, &diff);
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ dns_rdataset_init(&rdataset);
+
+ result = dns_db_createiterator(gdb, 0, &dbiter);
+ check_result(result, "dns_db_createiterator()");
+
+ for (result = dns_dbiterator_first(dbiter);
+ result == ISC_R_SUCCESS;
+ result = dns_dbiterator_next(dbiter)) {
+
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
+ check_result(result, "dns_db_allrdatasets()");
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, &rdataset);
+ rrset_remove_duplicates(name, &rdataset, &diff);
+ dns_rdataset_disassociate(&rdataset);
+ }
+ if (result != ISC_R_NOMORE)
+ fatal("rdatasets iteration failed.");
+ dns_rdatasetiter_destroy(&rdsiter);
+ dns_db_detachnode(gdb, &node);
+ }
+ if (result != ISC_R_NOMORE)
+ fatal("zone iteration failed.");
+
+ if (!ISC_LIST_EMPTY(diff.tuples)) {
+ result = dns_diff_applysilently(&diff, gdb, gversion);
+ check_result(result, "dns_diff_applysilently");
+ }
+ dns_diff_clear(&diff);
+ dns_dbiterator_destroy(&dbiter);
+}
+
/*
* Generate NSEC3 records for the zone.
*/
@@ -2546,7 +2703,7 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
*/
dns_dbiterator_pause(dbiter);
addnsec3(name, node, salt, salt_length, iterations,
- hashlist, zonettl);
+ hashlist, zone_soa_min_ttl);
dns_db_detachnode(gdb, &node);
/*
* Add NSEC3's for empty nodes. Use closest encloser logic.
@@ -2557,7 +2714,7 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
count--;
dns_name_split(nextname, count, NULL, nextname);
addnsec3(nextname, NULL, salt, salt_length,
- iterations, hashlist, zonettl);
+ iterations, hashlist, zone_soa_min_ttl);
}
}
dns_dbiterator_destroy(&dbiter);
@@ -2580,7 +2737,7 @@ loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
fatal("failed converting name '%s' to dns format: %s",
origin, isc_result_totext(result));
@@ -2600,90 +2757,169 @@ loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
* private keys from disk.
*/
static void
-loadzonekeys(dns_db_t *db) {
+loadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
dns_dbnode_t *node;
- dns_dbversion_t *currentversion;
+ dns_dbversion_t *currentversion = NULL;
isc_result_t result;
- dst_key_t *keys[20];
- unsigned int nkeys, i;
-
- currentversion = NULL;
- dns_db_currentversion(db, &currentversion);
+ dns_rdataset_t rdataset, keysigs, soasigs;
node = NULL;
- result = dns_db_findnode(db, gorigin, ISC_FALSE, &node);
+ result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS)
fatal("failed to find the zone's origin: %s",
isc_result_totext(result));
- result = dns_dnssec_findzonekeys(db, currentversion, node, gorigin,
- mctx, 20, keys, &nkeys);
- if (result == ISC_R_NOTFOUND)
- result = ISC_R_SUCCESS;
+ dns_db_currentversion(gdb, &currentversion);
+
+ dns_rdataset_init(&rdataset);
+ dns_rdataset_init(&soasigs);
+ dns_rdataset_init(&keysigs);
+
+ /* Make note of the keys which signed the SOA, if any */
+ result = dns_db_findrdataset(gdb, node, currentversion,
+ dns_rdatatype_soa, 0, 0,
+ &rdataset, &soasigs);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Preserve the TTL of the DNSKEY RRset, if any */
+ dns_rdataset_disassociate(&rdataset);
+ result = dns_db_findrdataset(gdb, node, currentversion,
+ dns_rdatatype_dnskey, 0, 0,
+ &rdataset, &keysigs);
+
if (result != ISC_R_SUCCESS)
- fatal("failed to find the zone keys: %s",
+ goto cleanup;
+
+ if (set_keyttl && keyttl != rdataset.ttl) {
+ fprintf(stderr, "User-specified TTL (%d) conflicts "
+ "with existing DNSKEY RRset TTL.\n",
+ keyttl);
+ fprintf(stderr, "Imported keys will use the RRSet "
+ "TTL (%d) instead.\n",
+ rdataset.ttl);
+ }
+ keyttl = rdataset.ttl;
+
+ /* Load keys corresponding to the existing DNSKEY RRset */
+ result = dns_dnssec_keylistfromrdataset(gorigin, directory, mctx,
+ &rdataset, &keysigs, &soasigs,
+ preserve_keys, load_public,
+ &keylist);
+ if (result != ISC_R_SUCCESS)
+ fatal("failed to load the zone keys: %s",
isc_result_totext(result));
- for (i = 0; i < nkeys; i++) {
- signer_key_t *key;
+ cleanup:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (dns_rdataset_isassociated(&keysigs))
+ dns_rdataset_disassociate(&keysigs);
+ if (dns_rdataset_isassociated(&soasigs))
+ dns_rdataset_disassociate(&soasigs);
+ dns_db_detachnode(gdb, &node);
+ dns_db_closeversion(gdb, &currentversion, ISC_FALSE);
+}
+
+static void
+loadexplicitkeys(char *keyfiles[], int n, isc_boolean_t setksk) {
+ isc_result_t result;
+ int i;
+
+ for (i = 0; i < n; i++) {
+ dns_dnsseckey_t *key = NULL;
+ dst_key_t *newkey = NULL;
+
+ result = dst_key_fromnamedfile(keyfiles[i], directory,
+ DST_TYPE_PUBLIC |
+ DST_TYPE_PRIVATE,
+ mctx, &newkey);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot load dnskey %s: %s", keyfiles[i],
+ isc_result_totext(result));
+
+ if (!dns_name_equal(gorigin, dst_key_name(newkey)))
+ fatal("key %s not at origin\n", keyfiles[i]);
+
+ if (!dst_key_isprivate(newkey))
+ fatal("cannot sign zone with non-private dnskey %s",
+ keyfiles[i]);
+
+ /* Skip any duplicates */
+ for (key = ISC_LIST_HEAD(keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ if (dst_key_id(key->key) == dst_key_id(newkey) &&
+ dst_key_alg(key->key) == dst_key_alg(newkey))
+ break;
+ }
+
+ if (key == NULL) {
+ /* We haven't seen this key before */
+ dns_dnsseckey_create(mctx, &newkey, &key);
+ ISC_LIST_APPEND(keylist, key, link);
+ key->source = dns_keysource_user;
+ } else {
+ dst_key_free(&key->key);
+ key->key = newkey;
+ }
+
+ key->force_publish = ISC_TRUE;
+ key->force_sign = ISC_TRUE;
- key = newkeystruct(keys[i], dst_key_isprivate(keys[i]));
- ISC_LIST_APPEND(keylist, key, link);
+ if (setksk)
+ key->ksk = ISC_TRUE;
}
- dns_db_detachnode(db, &node);
- dns_db_closeversion(db, &currentversion, ISC_FALSE);
}
-/*%
- * Finds all public zone keys in the zone.
- */
static void
-loadzonepubkeys(dns_db_t *db) {
- dns_dbversion_t *currentversion = NULL;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dst_key_t *pubkey;
- signer_key_t *key;
+report(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ putc('\n', stderr);
+}
+
+static void
+build_final_keylist() {
isc_result_t result;
+ dns_dbversion_t *ver = NULL;
+ dns_diff_t diff;
+ dns_dnsseckeylist_t matchkeys;
+ char name[DNS_NAME_FORMATSIZE];
- dns_db_currentversion(db, &currentversion);
+ /*
+ * Find keys that match this zone in the key repository.
+ */
+ ISC_LIST_INIT(matchkeys);
+ result = dns_dnssec_findmatchingkeys(gorigin, directory,
+ mctx, &matchkeys);
+ if (result == ISC_R_NOTFOUND)
+ result = ISC_R_SUCCESS;
+ check_result(result, "dns_dnssec_findmatchingkeys");
- result = dns_db_findnode(db, gorigin, ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS)
- fatal("failed to find the zone's origin: %s",
- isc_result_totext(result));
+ result = dns_db_newversion(gdb, &ver);
+ check_result(result, "dns_db_newversion");
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(db, node, currentversion,
- dns_rdatatype_dnskey, 0, 0, &rdataset,
- NULL);
+ dns_diff_init(mctx, &diff);
+
+ /*
+ * Update keylist with information from from the key repository.
+ */
+ dns_dnssec_updatekeys(&keylist, &matchkeys, NULL, gorigin, keyttl,
+ &diff, ignore_kskflag, mctx, report);
+
+ dns_name_format(gorigin, name, sizeof(name));
+
+ result = dns_diff_applysilently(&diff, gdb, ver);
if (result != ISC_R_SUCCESS)
- fatal("failed to find keys at the zone apex: %s",
- isc_result_totext(result));
- result = dns_rdataset_first(&rdataset);
- check_result(result, "dns_rdataset_first");
- while (result == ISC_R_SUCCESS) {
- pubkey = NULL;
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&rdataset, &rdata);
- result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx,
- &pubkey);
- if (result != ISC_R_SUCCESS)
- goto next;
- if (!dst_key_iszonekey(pubkey)) {
- dst_key_free(&pubkey);
- goto next;
- }
+ fatal("failed to update DNSKEY RRset at node '%s': %s",
+ name, isc_result_totext(result));
- key = newkeystruct(pubkey, ISC_FALSE);
- ISC_LIST_APPEND(keylist, key, link);
- next:
- result = dns_rdataset_next(&rdataset);
- }
- dns_rdataset_disassociate(&rdataset);
- dns_db_detachnode(db, &node);
- dns_db_closeversion(db, &currentversion, ISC_FALSE);
+ dns_db_closeversion(gdb, &ver, ISC_TRUE);
+
+ dns_diff_clear(&diff);
}
static void
@@ -2727,18 +2963,112 @@ warnifallksk(dns_db_t *db) {
dns_rdataset_disassociate(&rdataset);
dns_db_detachnode(db, &node);
dns_db_closeversion(db, &currentversion, ISC_FALSE);
- if (!have_non_ksk && !ignoreksk) {
+ if (!have_non_ksk && !ignore_kskflag) {
if (disable_zone_check)
- fprintf(stderr, "%s: warning: No non-KSK dnskey found. "
- "Supply non-KSK dnskey or use '-z'.\n",
+ fprintf(stderr, "%s: warning: No non-KSK DNSKEY found; "
+ "supply a ZSK or use '-z'.\n",
program);
else
- fatal("No non-KSK dnskey found. "
- "Supply non-KSK dnskey or use '-z'.");
+ fatal("No non-KSK DNSKEY found; "
+ "supply a ZSK or use '-z'.");
}
}
static void
+set_nsec3params(isc_boolean_t update_chain, isc_boolean_t set_salt,
+ isc_boolean_t set_optout, isc_boolean_t set_iter)
+{
+ isc_result_t result;
+ dns_dbversion_t *ver = NULL;
+ dns_dbnode_t *node = NULL;
+ dns_rdataset_t rdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_nsec3_t nsec3;
+ dns_fixedname_t fname;
+ dns_name_t *hashname;
+ unsigned char orig_salt[256];
+ size_t orig_saltlen;
+ dns_hash_t orig_hash;
+ isc_uint16_t orig_iter;
+
+ dns_db_currentversion(gdb, &ver);
+ dns_rdataset_init(&rdataset);
+
+ orig_saltlen = sizeof(orig_salt);
+ result = dns_db_getnsec3parameters(gdb, ver, &orig_hash, NULL,
+ &orig_iter, orig_salt,
+ &orig_saltlen);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ nsec_datatype = dns_rdatatype_nsec3;
+
+ if (!update_chain && set_salt) {
+ if (salt_length != orig_saltlen ||
+ memcmp(saltbuf, orig_salt, salt_length) != 0)
+ fatal("An NSEC3 chain exists with a different salt. "
+ "Use -u to update it.");
+ } else if (!set_salt) {
+ salt_length = orig_saltlen;
+ memcpy(saltbuf, orig_salt, orig_saltlen);
+ salt = saltbuf;
+ }
+
+ if (!update_chain && set_iter) {
+ if (nsec3iter != orig_iter)
+ fatal("An NSEC3 chain exists with different "
+ "iterations. Use -u to update it.");
+ } else if (!set_iter)
+ nsec3iter = orig_iter;
+
+ /*
+ * Find an NSEC3 record to get the current OPTOUT value.
+ * (This assumes all NSEC3 records agree.)
+ */
+
+ dns_fixedname_init(&fname);
+ hashname = dns_fixedname_name(&fname);
+ result = dns_nsec3_hashname(&fname, NULL, NULL,
+ gorigin, gorigin, dns_hash_sha1,
+ orig_iter, orig_salt, orig_saltlen);
+ check_result(result, "dns_nsec3_hashname");
+
+ result = dns_db_findnsec3node(gdb, hashname, ISC_FALSE, &node);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_db_findrdataset(gdb, node, ver, dns_rdatatype_nsec3,
+ 0, 0, &rdataset, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_rdataset_first(&rdataset);
+ check_result(result, "dns_rdataset_first");
+ dns_rdataset_current(&rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
+ check_result(result, "dns_rdata_tostruct");
+
+ if (!update_chain && set_optout) {
+ if (nsec3flags != nsec3.flags)
+ fatal("An NSEC3 chain exists with%s OPTOUT. "
+ "Use -u -%s to %s it.",
+ OPTOUT(nsec3.flags) ? "" : "out",
+ OPTOUT(nsec3.flags) ? "AA" : "A",
+ OPTOUT(nsec3.flags) ? "clear" : "set");
+ } else if (!set_optout)
+ nsec3flags = nsec3.flags;
+
+ dns_rdata_freestruct(&nsec3);
+
+ cleanup:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (node != NULL)
+ dns_db_detachnode(gdb, &node);
+ dns_db_closeversion(gdb, &ver, ISC_FALSE);
+}
+
+static void
writeset(const char *prefix, dns_rdatatype_t type) {
char *filename;
char namestr[DNS_NAME_FORMATSIZE];
@@ -2755,7 +3085,7 @@ writeset(const char *prefix, dns_rdatatype_t type) {
isc_buffer_t namebuf;
isc_region_t r;
isc_result_t result;
- signer_key_t *key;
+ dns_dnsseckey_t *key, *tmpkey;
unsigned char dsbuf[DNS_DS_BUFFERSIZE];
unsigned char keybuf[DST_KEY_MAXSIZE];
unsigned int filenamelen;
@@ -2767,13 +3097,13 @@ writeset(const char *prefix, dns_rdatatype_t type) {
check_result(result, "dns_name_tofilenametext");
isc_buffer_putuint8(&namebuf, 0);
filenamelen = strlen(prefix) + strlen(namestr);
- if (directory != NULL)
- filenamelen += strlen(directory) + 1;
+ if (dsdir != NULL)
+ filenamelen += strlen(dsdir) + 1;
filename = isc_mem_get(mctx, filenamelen + 1);
if (filename == NULL)
fatal("out of memory");
- if (directory != NULL)
- sprintf(filename, "%s/", directory);
+ if (dsdir != NULL)
+ sprintf(filename, "%s/", dsdir);
else
filename[0] = 0;
strcat(filename, prefix);
@@ -2781,22 +3111,6 @@ writeset(const char *prefix, dns_rdatatype_t type) {
dns_diff_init(mctx, &diff);
- for (key = ISC_LIST_HEAD(keylist);
- key != NULL;
- key = ISC_LIST_NEXT(key, link))
- if (!key->isksk) {
- have_non_ksk = ISC_TRUE;
- break;
- }
-
- for (key = ISC_LIST_HEAD(keylist);
- key != NULL;
- key = ISC_LIST_NEXT(key, link))
- if (key->isksk) {
- have_ksk = ISC_TRUE;
- break;
- }
-
if (type == dns_rdatatype_dlv) {
dns_name_t tname;
unsigned int labels;
@@ -2815,7 +3129,28 @@ writeset(const char *prefix, dns_rdatatype_t type) {
key != NULL;
key = ISC_LIST_NEXT(key, link))
{
- if (have_ksk && have_non_ksk && !key->isksk)
+ if (REVOKE(key->key))
+ continue;
+ if (isksk(key)) {
+ have_ksk = ISC_TRUE;
+ have_non_ksk = ISC_FALSE;
+ } else {
+ have_ksk = ISC_FALSE;
+ have_non_ksk = ISC_TRUE;
+ }
+ for (tmpkey = ISC_LIST_HEAD(keylist);
+ tmpkey != NULL;
+ tmpkey = ISC_LIST_NEXT(tmpkey, link)) {
+ if (dst_key_alg(key->key) != dst_key_alg(tmpkey->key))
+ continue;
+ if (REVOKE(tmpkey->key))
+ continue;
+ if (isksk(tmpkey))
+ have_ksk = ISC_TRUE;
+ else
+ have_non_ksk = ISC_TRUE;
+ }
+ if (have_ksk && have_non_ksk && !isksk(key))
continue;
dns_rdata_init(&rdata);
dns_rdata_init(&ds);
@@ -2848,7 +3183,7 @@ writeset(const char *prefix, dns_rdatatype_t type) {
} else
result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
- gorigin, zonettl,
+ gorigin, zone_soa_min_ttl,
&rdata, &tuple);
check_result(result, "dns_difftuple_create");
dns_diff_append(&diff, &tuple);
@@ -2893,6 +3228,9 @@ print_version(FILE *fp) {
fprintf(fp, "; dnssec_signzone version " VERSION "\n");
}
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(void) {
fprintf(stderr, "Usage:\n");
@@ -2903,14 +3241,18 @@ usage(void) {
fprintf(stderr, "Version: %s\n", VERSION);
fprintf(stderr, "Options: (default value in parenthesis) \n");
- fprintf(stderr, "\t-c class (IN)\n");
- fprintf(stderr, "\t-d directory\n");
- fprintf(stderr, "\t\tdirectory to find keyset files (.)\n");
+ fprintf(stderr, "\t-S:\tsmart signing: automatically finds key files\n"
+ "\t\tfor the zone and determines how they are to "
+ "be used\n");
+ fprintf(stderr, "\t-K directory:\n");
+ fprintf(stderr, "\t\tdirectory to find key files (.)\n");
+ fprintf(stderr, "\t-d directory:\n");
+ fprintf(stderr, "\t\tdirectory to find dsset-* files (.)\n");
fprintf(stderr, "\t-g:\t");
- fprintf(stderr, "generate DS records from keyset files\n");
+ fprintf(stderr, "update DS records based on child zones' "
+ "dsset-* files\n");
fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n");
- fprintf(stderr, "\t\tRRSIG start time - absolute|offset "
- "(now - 1 hour)\n");
+ fprintf(stderr, "\t\tRRSIG start time - absolute|offset (now - 1 hour)\n");
fprintf(stderr, "\t-e [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n");
fprintf(stderr, "\t\tRRSIG end time - absolute|from start|from now "
"(now + 30 days)\n");
@@ -2918,8 +3260,7 @@ usage(void) {
fprintf(stderr, "\t\tcycle interval - resign "
"if < interval from end ( (end-start)/4 )\n");
fprintf(stderr, "\t-j jitter:\n");
- fprintf(stderr, "\t\trandomize signature end time up to jitter "
- "seconds\n");
+ fprintf(stderr, "\t\trandomize signature end time up to jitter seconds\n");
fprintf(stderr, "\t-v debuglevel (0)\n");
fprintf(stderr, "\t-o origin:\n");
fprintf(stderr, "\t\tzone origin (name of zonefile)\n");
@@ -2936,20 +3277,33 @@ usage(void) {
fprintf(stderr, "\t\ta file containing random data\n");
fprintf(stderr, "\t-a:\t");
fprintf(stderr, "verify generated signatures\n");
+ fprintf(stderr, "\t-c class (IN)\n");
+ fprintf(stderr, "\t-E engine:\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, "\t\tname of an OpenSSL engine to use "
+ "(default is \"pkcs11\")\n");
+#else
+ fprintf(stderr, "\t\tname of an OpenSSL engine to use\n");
+#endif
fprintf(stderr, "\t-p:\t");
fprintf(stderr, "use pseudorandom data (faster but less secure)\n");
fprintf(stderr, "\t-P:\t");
fprintf(stderr, "disable post-sign verification\n");
+ fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs\n");
fprintf(stderr, "\t-t:\t");
fprintf(stderr, "print statistics\n");
+ fprintf(stderr, "\t-u:\t");
+ fprintf(stderr, "update or replace an existing NSEC/NSEC3 chain\n");
+ fprintf(stderr, "\t-x:\tsign DNSKEY record with KSKs only, not ZSKs\n");
+ fprintf(stderr, "\t-z:\tsign all records with KSKs\n");
+ fprintf(stderr, "\t-C:\tgenerate a keyset file, for compatibility\n"
+ "\t\twith older versions of dnssec-signzone -g\n");
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");
+ fprintf(stderr, "\t-3 NSEC3 salt\n");
+ fprintf(stderr, "\t-H NSEC3 iterations (10)\n");
+ fprintf(stderr, "\t-A NSEC3 optout\n");
fprintf(stderr, "\n");
@@ -3001,10 +3355,15 @@ main(int argc, char *argv[]) {
int ndskeys = 0;
char *endp;
isc_time_t timer_start, timer_finish;
- signer_key_t *key;
+ dns_dnsseckey_t *key;
isc_result_t result;
isc_log_t *log = NULL;
isc_boolean_t pseudorandom = ISC_FALSE;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
unsigned int eflags;
isc_boolean_t free_output = ISC_FALSE;
int tempfilelen;
@@ -3012,13 +3371,15 @@ 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;
+ isc_boolean_t smartsign = ISC_FALSE;
+ isc_boolean_t make_keyset = ISC_FALSE;
+ isc_boolean_t set_salt = ISC_FALSE;
+ isc_boolean_t set_optout = ISC_FALSE;
+ isc_boolean_t set_iter = ISC_FALSE;
-#define CMDLINE_FLAGS "3:aAc:d:e:f:FghH:i:I:j:k:l:m:n:N:o:O:pPr:s:StUv:z"
+#define CMDLINE_FLAGS \
+ "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:pPr:s:ST:tuUv:xz"
/*
* Process memory debugging argument first.
@@ -3058,7 +3419,9 @@ main(int argc, char *argv[]) {
while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
switch (ch) {
case '3':
- if (strcmp(isc_commandline_argument, "-")) {
+ set_salt = ISC_TRUE;
+ nsec_datatype = dns_rdatatype_nsec3;
+ if (strcmp(isc_commandline_argument, "-") != 0) {
isc_buffer_t target;
char *sarg;
@@ -3068,29 +3431,42 @@ main(int argc, char *argv[]) {
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;
+ set_optout = ISC_TRUE;
+ if (OPTOUT(nsec3flags))
+ nsec3flags &= ~DNS_NSEC3FLAG_OPTOUT;
+ else
+ nsec3flags |= DNS_NSEC3FLAG_OPTOUT;
break;
case 'a':
tryverify = ISC_TRUE;
break;
+ case 'C':
+ make_keyset = ISC_TRUE;
+ break;
+
case 'c':
classname = isc_commandline_argument;
break;
case 'd':
- directory = isc_commandline_argument;
+ dsdir = isc_commandline_argument;
+ if (strlen(dsdir) == 0U)
+ fatal("DS directory must be non-empty string");
+ result = try_dir(dsdir);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot open directory %s: %s",
+ dsdir, isc_result_totext(result));
+ break;
+
+ case 'E':
+ engine = isc_commandline_argument;
break;
case 'e':
@@ -3106,11 +3482,11 @@ main(int argc, char *argv[]) {
break;
case 'H':
- iterations = strtoul(isc_commandline_argument,
- &endp, 0);
+ set_iter = ISC_TRUE;
+ nsec3iter = strtoul(isc_commandline_argument, &endp, 0);
if (*endp != '\0')
fatal("iterations must be numeric");
- if (iterations > 0xffffU)
+ if (nsec3iter > 0xffffU)
fatal("iterations too big");
break;
@@ -3118,6 +3494,10 @@ main(int argc, char *argv[]) {
usage();
break;
+ case 'I':
+ inputformatstr = isc_commandline_argument;
+ break;
+
case 'i':
endp = NULL;
cycle = strtol(isc_commandline_argument, &endp, 0);
@@ -3126,10 +3506,6 @@ main(int argc, char *argv[]) {
"positive");
break;
- case 'I':
- inputformatstr = isc_commandline_argument;
- break;
-
case 'j':
endp = NULL;
jitter = strtol(isc_commandline_argument, &endp, 0);
@@ -3137,6 +3513,10 @@ main(int argc, char *argv[]) {
fatal("jitter must be numeric and positive");
break;
+ case 'K':
+ directory = isc_commandline_argument;
+ break;
+
case 'k':
if (ndskeys == MAXDSKEYS)
fatal("too many key-signing keys specified");
@@ -3150,14 +3530,18 @@ main(int argc, char *argv[]) {
dns_fixedname_init(&dlv_fixed);
dlv = dns_fixedname_name(&dlv_fixed);
- result = dns_name_fromtext(dlv, &b, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(dlv, &b, dns_rootname, 0,
+ NULL);
check_result(result, "dns_name_fromtext(dlv)");
break;
case 'm':
break;
+ case 'N':
+ serialformatstr = isc_commandline_argument;
+ break;
+
case 'n':
endp = NULL;
ntasks = strtol(isc_commandline_argument, &endp, 0);
@@ -3165,38 +3549,38 @@ main(int argc, char *argv[]) {
fatal("number of cpus must be numeric");
break;
- case 'N':
- serialformatstr = isc_commandline_argument;
+ case 'O':
+ outputformatstr = isc_commandline_argument;
break;
case 'o':
origin = isc_commandline_argument;
break;
- case 'O':
- outputformatstr = isc_commandline_argument;
+ case 'P':
+ disable_zone_check = ISC_TRUE;
break;
case 'p':
pseudorandom = ISC_TRUE;
break;
- case 'P':
- disable_zone_check = ISC_TRUE;
- break;
-
case 'r':
setup_entropy(mctx, isc_commandline_argument, &ectx);
break;
+ case 'S':
+ smartsign = ISC_TRUE;
+ break;
+
case 's':
startstr = isc_commandline_argument;
break;
- case 'S':
- /* This is intentionally undocumented */
- /* -S: simple output style */
- masterstyle = &dns_master_style_simple;
+ case 'T':
+ endp = NULL;
+ set_keyttl = ISC_TRUE;
+ keyttl = strtottl(isc_commandline_argument);
break;
case 't':
@@ -3207,6 +3591,10 @@ main(int argc, char *argv[]) {
unknownalg = ISC_TRUE;
break;
+ case 'u':
+ update_chain = ISC_TRUE;
+ break;
+
case 'v':
endp = NULL;
verbose = strtol(isc_commandline_argument, &endp, 0);
@@ -3214,8 +3602,12 @@ main(int argc, char *argv[]) {
fatal("verbose level must be numeric");
break;
+ case 'x':
+ keyset_kskonly = ISC_TRUE;
+ break;
+
case 'z':
- ignoreksk = ISC_TRUE;
+ ignore_kskflag = ISC_TRUE;
break;
case 'F':
@@ -3245,20 +3637,21 @@ main(int argc, char *argv[]) {
if (result != ISC_R_SUCCESS)
fatal("could not create hash context");
- result = dst_lib_init(mctx, ectx, eflags);
+ result = dst_lib_init2(mctx, ectx, engine, eflags);
if (result != ISC_R_SUCCESS)
- fatal("could not initialize dst");
+ fatal("could not initialize dst: %s",
+ isc_result_totext(result));
isc_stdtime_get(&now);
- if (startstr != NULL)
+ if (startstr != NULL) {
starttime = strtotime(startstr, now, now);
- else
+ } else
starttime = now - 3600; /* Allow for some clock skew. */
- if (endstr != NULL)
+ if (endstr != NULL) {
endtime = strtotime(endstr, now, starttime);
- else
+ } else
endtime = starttime + (30 * 24 * 60 * 60);
if (cycle == -1)
@@ -3270,6 +3663,9 @@ main(int argc, char *argv[]) {
rdclass = strtoclass(classname);
+ if (directory == NULL)
+ directory = ".";
+
setup_logging(verbose, mctx, &log);
argc -= isc_commandline_index;
@@ -3335,7 +3731,19 @@ main(int argc, char *argv[]) {
loadzone(file, origin, rdclass, &gdb);
gorigin = dns_db_origin(gdb);
gclass = dns_db_class(gdb);
- zonettl = soattl();
+ get_soa_ttls();
+
+ if (!set_keyttl)
+ keyttl = soa_ttl;
+
+ /*
+ * Check for any existing NSEC3 parameters in the zone,
+ * and use them as defaults if -u was not specified.
+ */
+ if (update_chain && !set_optout && !set_iter && !set_salt)
+ nsec_datatype = dns_rdatatype_nsec;
+ else
+ set_nsec3params(update_chain, set_salt, set_optout, set_iter);
if (IS_NSEC3) {
isc_boolean_t answer;
@@ -3356,95 +3764,42 @@ main(int argc, char *argv[]) {
ISC_LIST_INIT(keylist);
isc_rwlock_init(&keylist_lock, 0, 0);
- if (argc == 0) {
- loadzonekeys(gdb);
- } else {
- for (i = 0; i < argc; i++) {
- dst_key_t *newkey = NULL;
-
- result = dst_key_fromnamedfile(argv[i],
- DST_TYPE_PUBLIC |
- DST_TYPE_PRIVATE,
- mctx, &newkey);
- if (result != ISC_R_SUCCESS)
- 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;
- if (dst_key_id(dkey) == dst_key_id(newkey) &&
- dst_key_alg(dkey) == dst_key_alg(newkey) &&
- dns_name_equal(dst_key_name(dkey),
- dst_key_name(newkey)))
- {
- if (!dst_key_isprivate(dkey))
- fatal("cannot sign zone with "
- "non-private dnskey %s",
- argv[i]);
- break;
- }
- key = ISC_LIST_NEXT(key, link);
- }
- if (key == NULL) {
- key = newkeystruct(newkey, ISC_TRUE);
- key->commandline = ISC_TRUE;
- ISC_LIST_APPEND(keylist, key, link);
- } else
- dst_key_free(&newkey);
- }
-
- loadzonepubkeys(gdb);
- }
-
- for (i = 0; i < ndskeys; i++) {
- dst_key_t *newkey = NULL;
-
- result = dst_key_fromnamedfile(dskeyfile[i],
- DST_TYPE_PUBLIC |
- DST_TYPE_PRIVATE,
- mctx, &newkey);
- if (result != ISC_R_SUCCESS)
- fatal("cannot load dnskey %s: %s", dskeyfile[i],
- isc_result_totext(result));
+ /*
+ * Fill keylist with:
+ * 1) Keys listed in the DNSKEY set that have
+ * private keys associated, *if* no keys were
+ * set on the command line.
+ * 2) ZSKs set on the command line
+ * 3) KSKs set on the command line
+ * 4) Any keys remaining in the DNSKEY set which
+ * do not have private keys associated and were
+ * not specified on the command line.
+ */
+ if (argc == 0 || smartsign)
+ loadzonekeys(!smartsign, ISC_FALSE);
+ loadexplicitkeys(argv, argc, ISC_FALSE);
+ loadexplicitkeys(dskeyfile, ndskeys, ISC_TRUE);
+ loadzonekeys(!smartsign, ISC_TRUE);
- if (!dns_name_equal(gorigin, dst_key_name(newkey)))
- fatal("key %s not at origin\n", dskeyfile[i]);
+ /*
+ * If we're doing smart signing, look in the key repository for
+ * key files with metadata, and merge them with the keylist
+ * we have now.
+ */
+ if (smartsign)
+ build_final_keylist();
- key = ISC_LIST_HEAD(keylist);
- while (key != NULL) {
- dst_key_t *dkey = key->key;
- if (dst_key_id(dkey) == dst_key_id(newkey) &&
- dst_key_alg(dkey) == dst_key_alg(newkey) &&
- dns_name_equal(dst_key_name(dkey),
- dst_key_name(newkey)))
- {
- /* Override key flags. */
- key->issigningkey = ISC_TRUE;
- key->isksk = ISC_TRUE;
- key->isdsk = ISC_FALSE;
- dst_key_free(&dkey);
- key->key = newkey;
- break;
- }
- key = ISC_LIST_NEXT(key, link);
- }
- if (key == NULL) {
- /* Override dnskey flags. */
- key = newkeystruct(newkey, ISC_TRUE);
- key->isksk = ISC_TRUE;
- key->isdsk = ISC_FALSE;
- ISC_LIST_APPEND(keylist, key, link);
- }
+ /* Now enumerate the key list */
+ for (key = ISC_LIST_HEAD(keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ key->index = keycount++;
}
- if (ISC_LIST_EMPTY(keylist)) {
+ if (keycount == 0) {
if (disable_zone_check)
fprintf(stderr, "%s: warning: No keys specified "
- "or found\n", program);
+ "or found\n", program);
else
fatal("No signing keys specified or found.");
nokeys = ISC_TRUE;
@@ -3454,7 +3809,7 @@ main(int argc, char *argv[]) {
unsigned int max;
result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max);
check_result(result, "dns_nsec3_maxiterations()");
- if (iterations > max)
+ if (nsec3iter > max)
fatal("NSEC3 iterations too big for weakest DNSKEY "
"strength. Maximum iterations allowed %u.", max);
}
@@ -3478,15 +3833,18 @@ main(int argc, char *argv[]) {
break;
}
+ remove_duplicates();
+
if (IS_NSEC3)
- nsec3ify(dns_hash_sha1, iterations, salt, salt_length,
+ nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length,
&hashlist);
else
nsecify();
if (!nokeys) {
- writeset("keyset-", dns_rdatatype_dnskey);
writeset("dsset-", dns_rdatatype_ds);
+ if (make_keyset)
+ writeset("keyset-", dns_rdatatype_dnskey);
if (dlv != NULL) {
writeset("dlvset-", dns_rdatatype_dlv);
}
@@ -3591,8 +3949,7 @@ main(int argc, char *argv[]) {
while (!ISC_LIST_EMPTY(keylist)) {
key = ISC_LIST_HEAD(keylist);
ISC_LIST_UNLINK(keylist, key, link);
- dst_key_free(&key->key);
- isc_mem_put(mctx, key, sizeof(signer_key_t));
+ dns_dnsseckey_destroy(mctx, &key);
}
isc_mem_put(mctx, tempfile, tempfilelen);
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.docbook b/contrib/bind9/bin/dnssec/dnssec-signzone.docbook
index 87a801e..51a1496 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.docbook
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.docbook
@@ -18,10 +18,10 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-signzone.docbook,v 1.31.44.8 2009-11-06 21:36:22 each Exp $ -->
+<!-- $Id: dnssec-signzone.docbook,v 1.44 2009-12-03 23:18:16 each Exp $ -->
<refentry id="man.dnssec-signzone">
<refentryinfo>
- <date>June 08, 2009</date>
+ <date>June 05, 2009</date>
</refentryinfo>
<refmeta>
@@ -60,10 +60,12 @@
<arg><option>-a</option></arg>
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
<arg><option>-d <replaceable class="parameter">directory</replaceable></option></arg>
+ <arg><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
<arg><option>-e <replaceable class="parameter">end-time</replaceable></option></arg>
<arg><option>-f <replaceable class="parameter">output-file</replaceable></option></arg>
<arg><option>-g</option></arg>
<arg><option>-h</option></arg>
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
<arg><option>-k <replaceable class="parameter">key</replaceable></option></arg>
<arg><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
<arg><option>-i <replaceable class="parameter">interval</replaceable></option></arg>
@@ -75,9 +77,13 @@
<arg><option>-p</option></arg>
<arg><option>-P</option></arg>
<arg><option>-r <replaceable class="parameter">randomdev</replaceable></option></arg>
+ <arg><option>-S</option></arg>
<arg><option>-s <replaceable class="parameter">start-time</replaceable></option></arg>
+ <arg><option>-T <replaceable class="parameter">ttl</replaceable></option></arg>
<arg><option>-t</option></arg>
+ <arg><option>-u</option></arg>
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-x</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>
@@ -92,10 +98,10 @@
<para><command>dnssec-signzone</command>
signs a zone. It generates
NSEC and RRSIG records and produces a signed version of the
- zone. It also generates a <filename>keyset-</filename> file containing
- the key-signing keys for the zone, and if signing a zone which
- contains delegations, it can optionally generate DS records for
- the child zones from their <filename>keyset-</filename> files.
+ zone. The security status of delegations from the signed zone
+ (that is, whether the child zones are secure or not) is
+ determined by the presence or absence of a
+ <filename>keyset</filename> file for each child zone.
</para>
</refsect1>
@@ -122,31 +128,37 @@
</varlistentry>
<varlistentry>
- <term>-k <replaceable class="parameter">key</replaceable></term>
+ <term>-C</term>
<listitem>
<para>
- Treat specified key as a key signing key ignoring any
- key flags. This option may be specified multiple times.
+ Compatibility mode: Generate a
+ <filename>keyset-<replaceable>zonename</replaceable></filename>
+ file in addition to
+ <filename>dsset-<replaceable>zonename</replaceable></filename>
+ when signing a zone, for use by older versions of
+ <command>dnssec-signzone</command>.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>-l <replaceable class="parameter">domain</replaceable></term>
+ <term>-d <replaceable class="parameter">directory</replaceable></term>
<listitem>
<para>
- Generate a DLV set in addition to the key (DNSKEY) and DS sets.
- The domain is appended to the name of the records.
+ Look for <filename>dsset-</filename> or
+ <filename>keyset-</filename> files in <option>directory</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>-d <replaceable class="parameter">directory</replaceable></term>
+ <term>-E <replaceable class="parameter">engine</replaceable></term>
<listitem>
<para>
- Look for <filename>keyset</filename> files in
- <option>directory</option> as the directory
+ Uses a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
</para>
</listitem>
</varlistentry>
@@ -155,10 +167,39 @@
<term>-g</term>
<listitem>
<para>
- If the zone contains any delegations, and there are
- <filename>keyset-</filename> files for any of the child zones,
- then DS records for the child zones will be generated from the
- keys in those files. Existing DS records will be removed.
+ Generate DS records for child zones from
+ <filename>dsset-</filename> or <filename>keyset-</filename>
+ file. Existing DS records will be removed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ Key repository: Specify a directory to search for DNSSEC keys.
+ If not specified, defaults to the current directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-k <replaceable class="parameter">key</replaceable></term>
+ <listitem>
+ <para>
+ Treat specified key as a key signing key ignoring any
+ key flags. This option may be specified multiple times.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-l <replaceable class="parameter">domain</replaceable></term>
+ <listitem>
+ <para>
+ Generate a DLV set in addition to the key (DNSKEY) and DS sets.
+ The domain is appended to the name of the records.
</para>
</listitem>
</varlistentry>
@@ -190,6 +231,8 @@
the start time. A time relative to the current time is
indicated with now+N. If no <option>end-time</option> is
specified, 30 days from the start time is used as a default.
+ <option>end-time</option> must be later than
+ <option>start-time</option>.
</para>
</listitem>
</varlistentry>
@@ -396,6 +439,89 @@
</varlistentry>
<varlistentry>
+ <term>-S</term>
+ <listitem>
+ <para>
+ Smart signing: Instructs <command>dnssec-signzone</command> to
+ search the key repository for keys that match the zone being
+ signed, and to include them in the zone if appropriate.
+ </para>
+ <para>
+ When a key is found, its timing metadata is examined to
+ determine how it should be used, according to the following
+ rules. Each successive rule takes priority over the prior
+ ones:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <listitem>
+ <para>
+ If no timing metadata has been set for the key, the key is
+ published in the zone and used to sign the zone.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <listitem>
+ <para>
+ If the key's publication date is set and is in the past, the
+ key is published in the zone.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <listitem>
+ <para>
+ If the key's activation date is set and in the past, the
+ key is published (regardless of publication date) and
+ used to sign the zone.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <listitem>
+ <para>
+ If the key's revocation date is set and in the past, and the
+ key is published, then the key is revoked, and the revoked key
+ is used to sign the zone.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <listitem>
+ <para>
+ If either of the key's unpublication or deletion dates are set
+ and in the past, the key is NOT published or used to sign the
+ zone, regardless of any other metadata.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-T <replaceable class="parameter">ttl</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the TTL to be used for new DNSKEY records imported
+ into the zone from the key repository. If not specified,
+ the default is the minimum TTL value from the zone's SOA
+ record. This option is ignored when signing without
+ <option>-S</option>, since DNSKEY records are not imported
+ from the key repository in that case. It is also ignored if
+ there are any pre-existing DNSKEY records at the zone apex,
+ in which case new records' TTL values will be set to match
+ them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-t</term>
<listitem>
<para>
@@ -405,6 +531,20 @@
</varlistentry>
<varlistentry>
+ <term>-u</term>
+ <listitem>
+ <para>
+ Update NSEC/NSEC3 chain when re-signing a previously signed
+ zone. With this option, a zone signed with NSEC can be
+ switched to NSEC3, or a zone signed with NSEC3 can
+ be switch to NSEC or to NSEC3 with different parameters.
+ Without this option, <command>dnssec-signzone</command> will
+ retain the existing chain when re-signing.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-v <replaceable class="parameter">level</replaceable></term>
<listitem>
<para>
@@ -414,10 +554,26 @@
</varlistentry>
<varlistentry>
+ <term>-x</term>
+ <listitem>
+ <para>
+ Only sign the DNSKEY RRset with key-signing keys, and omit
+ signatures from zone-signing keys. (This is similar to the
+ <command>dnssec-dnskey-kskonly yes;</command> zone option in
+ <command>named</command>.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-z</term>
<listitem>
<para>
- Ignore KSK flag on key when determining what to sign.
+ Ignore KSK flag on key when determining what to sign. This
+ causes KSK-flagged keys to sign all records, not just the
+ DNSKEY RRset. (This is similar to the
+ <command>update-check-ksk no;</command> zone option in
+ <command>named</command>.)
</para>
</listitem>
</varlistentry>
@@ -426,7 +582,7 @@
<term>-3 <replaceable class="parameter">salt</replaceable></term>
<listitem>
<para>
- Generate a NSEC3 chain with the given hex encoded salt.
+ Generate an 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>
@@ -437,8 +593,8 @@
<term>-H <replaceable class="parameter">iterations</replaceable></term>
<listitem>
<para>
- When generating a NSEC3 chain use this many interations. The
- default is 100.
+ When generating an NSEC3 chain, use this many interations. The
+ default is 10.
</para>
</listitem>
</varlistentry>
@@ -447,10 +603,16 @@
<term>-A</term>
<listitem>
<para>
- When generating a NSEC3 chain set the OPTOUT flag on all
+ When generating an NSEC3 chain set the OPTOUT flag on all
NSEC3 records and do not generate NSEC3 records for insecure
delegations.
</para>
+ <para>
+ Using this option twice (i.e., <option>-AA</option>)
+ turns the OPTOUT flag off for all records. This is useful
+ when using the <option>-u</option> option to modify an NSEC3
+ chain which previously had OPTOUT set.
+ </para>
</listitem>
</varlistentry>
@@ -484,10 +646,11 @@
<para>
The following command signs the <userinput>example.com</userinput>
zone with the DSA key generated by <command>dnssec-keygen</command>
- (Kexample.com.+003+17247). The zone's keys must be in the master
- file (<filename>db.example.com</filename>). This invocation looks
- for <filename>keyset</filename> files, in the current directory,
- so that DS records can be generated from them (<command>-g</command>).
+ (Kexample.com.+003+17247). Because the <command>-S</command> option
+ is not being used, the zone's keys must be in the master file
+ (<filename>db.example.com</filename>). This invocation looks
+ for <filename>dsset</filename> files, in the current directory,
+ so that DS records can be imported from them (<command>-g</command>).
</para>
<programlisting>% dnssec-signzone -g -o example.com db.example.com \
Kexample.com.+003+17247
@@ -510,33 +673,6 @@ db.example.com.signed
</refsect1>
<refsect1>
- <title>KNOWN BUGS</title>
- <para>
- <command>dnssec-signzone</command> was designed so that it could
- sign a zone partially, using only a subset of the DNSSEC keys
- needed to produce a fully-signed zone. This permits a zone
- administrator, for example, to sign a zone with one key on one
- machine, move the resulting partially-signed zone to a second
- machine, and sign it again with a second key.
- </para>
- <para>
- An unfortunate side-effect of this flexibility is that
- <command>dnssec-signzone</command> does not check to make sure
- it's signing a zone with any valid keys at all. An attempt to
- sign a zone without any keys will appear to succeed, producing
- a "signed" zone with no signatures. There is no warning issued
- when a zone is not fully signed.
- </para>
-
- <para>
- This will be corrected in a future release. In the meantime, ISC
- recommends examining the output of <command>dnssec-signzone</command>
- to confirm that the zone is properly signed by all keys before
- using it.
- </para>
- </refsect1>
-
- <refsect1>
<title>SEE ALSO</title>
<para><citerefentry>
<refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.html b/contrib/bind9/bin/dnssec/dnssec-signzone.html
index 1d4ecff..28e7158 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.33.44.8 2009-11-07 01:56:11 tbox Exp $ -->
+<!-- $Id: dnssec-signzone.html,v 1.45 2009-12-04 01:13:44 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,21 +29,21 @@
</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">-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 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>engine</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>directory</code></em></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">-P</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-S</code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-T <em class="replaceable"><code>ttl</code></em></code>] [<code class="option">-t</code>] [<code class="option">-u</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-x</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="id2543558"></a><h2>DESCRIPTION</h2>
+<a name="id2543596"></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
- zone. It also generates a <code class="filename">keyset-</code> file containing
- the key-signing keys for the zone, and if signing a zone which
- contains delegations, it can optionally generate DS records for
- the child zones from their <code class="filename">keyset-</code> files.
+ zone. The security status of delegations from the signed zone
+ (that is, whether the child zones are secure or not) is
+ determined by the presence or absence of a
+ <code class="filename">keyset</code> file for each child zone.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543576"></a><h2>OPTIONS</h2>
+<a name="id2543611"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a</span></dt>
<dd><p>
@@ -53,6 +53,38 @@
<dd><p>
Specifies the DNS class of the zone.
</p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: Generate a
+ <code class="filename">keyset-<em class="replaceable"><code>zonename</code></em></code>
+ file in addition to
+ <code class="filename">dsset-<em class="replaceable"><code>zonename</code></em></code>
+ when signing a zone, for use by older versions of
+ <span><strong class="command">dnssec-signzone</strong></span>.
+ </p></dd>
+<dt><span class="term">-d <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Look for <code class="filename">dsset-</code> or
+ <code class="filename">keyset-</code> files in <code class="option">directory</code>.
+ </p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Uses a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </p></dd>
+<dt><span class="term">-g</span></dt>
+<dd><p>
+ Generate DS records for child zones from
+ <code class="filename">dsset-</code> or <code class="filename">keyset-</code>
+ file. Existing DS records will be removed.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Key repository: Specify a directory to search for DNSSEC keys.
+ If not specified, defaults to the current directory.
+ </p></dd>
<dt><span class="term">-k <em class="replaceable"><code>key</code></em></span></dt>
<dd><p>
Treat specified key as a key signing key ignoring any
@@ -63,18 +95,6 @@
Generate a DLV set in addition to the key (DNSKEY) and DS sets.
The domain is appended to the name of the records.
</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
- </p></dd>
-<dt><span class="term">-g</span></dt>
-<dd><p>
- If the zone contains any delegations, and there are
- <code class="filename">keyset-</code> files for any of the child zones,
- then DS records for the child zones will be generated from the
- keys in those files. Existing DS records will be removed.
- </p></dd>
<dt><span class="term">-s <em class="replaceable"><code>start-time</code></em></span></dt>
<dd><p>
Specify the date and time when the generated RRSIG records
@@ -95,6 +115,8 @@
the start time. A time relative to the current time is
indicated with now+N. If no <code class="option">end-time</code> is
specified, 30 days from the start time is used as a default.
+ <code class="option">end-time</code> must be later than
+ <code class="option">start-time</code>.
</p></dd>
<dt><span class="term">-f <em class="replaceable"><code>output-file</code></em></span></dt>
<dd><p>
@@ -229,35 +251,119 @@
<code class="filename">keyboard</code> indicates that keyboard
input should be used.
</p></dd>
+<dt><span class="term">-S</span></dt>
+<dd>
+<p>
+ Smart signing: Instructs <span><strong class="command">dnssec-signzone</strong></span> to
+ search the key repository for keys that match the zone being
+ signed, and to include them in the zone if appropriate.
+ </p>
+<p>
+ When a key is found, its timing metadata is examined to
+ determine how it should be used, according to the following
+ rules. Each successive rule takes priority over the prior
+ ones:
+ </p>
+<div class="variablelist"><dl>
+<dt></dt>
+<dd><p>
+ If no timing metadata has been set for the key, the key is
+ published in the zone and used to sign the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If the key's publication date is set and is in the past, the
+ key is published in the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If the key's activation date is set and in the past, the
+ key is published (regardless of publication date) and
+ used to sign the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If the key's revocation date is set and in the past, and the
+ key is published, then the key is revoked, and the revoked key
+ is used to sign the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If either of the key's unpublication or deletion dates are set
+ and in the past, the key is NOT published or used to sign the
+ zone, regardless of any other metadata.
+ </p></dd>
+</dl></div>
+</dd>
+<dt><span class="term">-T <em class="replaceable"><code>ttl</code></em></span></dt>
+<dd><p>
+ Specifies the TTL to be used for new DNSKEY records imported
+ into the zone from the key repository. If not specified,
+ the default is the minimum TTL value from the zone's SOA
+ record. This option is ignored when signing without
+ <code class="option">-S</code>, since DNSKEY records are not imported
+ from the key repository in that case. It is also ignored if
+ there are any pre-existing DNSKEY records at the zone apex,
+ in which case new records' TTL values will be set to match
+ them.
+ </p></dd>
<dt><span class="term">-t</span></dt>
<dd><p>
Print statistics at completion.
</p></dd>
+<dt><span class="term">-u</span></dt>
+<dd><p>
+ Update NSEC/NSEC3 chain when re-signing a previously signed
+ zone. With this option, a zone signed with NSEC can be
+ switched to NSEC3, or a zone signed with NSEC3 can
+ be switch to NSEC or to NSEC3 with different parameters.
+ Without this option, <span><strong class="command">dnssec-signzone</strong></span> will
+ retain the existing chain when re-signing.
+ </p></dd>
<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
<dd><p>
Sets the debugging level.
</p></dd>
+<dt><span class="term">-x</span></dt>
+<dd><p>
+ Only sign the DNSKEY RRset with key-signing keys, and omit
+ signatures from zone-signing keys. (This is similar to the
+ <span><strong class="command">dnssec-dnskey-kskonly yes;</strong></span> zone option in
+ <span><strong class="command">named</strong></span>.)
+ </p></dd>
<dt><span class="term">-z</span></dt>
<dd><p>
- Ignore KSK flag on key when determining what to sign.
+ Ignore KSK flag on key when determining what to sign. This
+ causes KSK-flagged keys to sign all records, not just the
+ DNSKEY RRset. (This is similar to the
+ <span><strong class="command">update-check-ksk no;</strong></span> zone option in
+ <span><strong class="command">named</strong></span>.)
</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.
+ Generate an 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.
+ When generating an NSEC3 chain, use this many interations. The
+ default is 10.
</p></dd>
<dt><span class="term">-A</span></dt>
-<dd><p>
- When generating a NSEC3 chain set the OPTOUT flag on all
+<dd>
+<p>
+ When generating an NSEC3 chain set the OPTOUT flag on all
NSEC3 records and do not generate NSEC3 records for insecure
delegations.
- </p></dd>
+ </p>
+<p>
+ Using this option twice (i.e., <code class="option">-AA</code>)
+ turns the OPTOUT flag off for all records. This is useful
+ when using the <code class="option">-u</code> option to modify an NSEC3
+ chain which previously had OPTOUT set.
+ </p>
+</dd>
<dt><span class="term">zonefile</span></dt>
<dd><p>
The file containing the zone to be signed.
@@ -273,14 +379,15 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544503"></a><h2>EXAMPLE</h2>
+<a name="id2544896"></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>
- (Kexample.com.+003+17247). The zone's keys must be in the master
- file (<code class="filename">db.example.com</code>). This invocation looks
- for <code class="filename">keyset</code> files, in the current directory,
- so that DS records can be generated from them (<span><strong class="command">-g</strong></span>).
+ (Kexample.com.+003+17247). Because the <span><strong class="command">-S</strong></span> option
+ is not being used, the zone's keys must be in the master file
+ (<code class="filename">db.example.com</code>). This invocation looks
+ for <code class="filename">dsset</code> files, in the current directory,
+ so that DS records can be imported from them (<span><strong class="command">-g</strong></span>).
</p>
<pre class="programlisting">% dnssec-signzone -g -o example.com db.example.com \
Kexample.com.+003+17247
@@ -302,39 +409,14 @@ db.example.com.signed
%</pre>
</div>
<div class="refsect1" lang="en">
-<a name="id2544554"></a><h2>KNOWN BUGS</h2>
-<p>
- <span><strong class="command">dnssec-signzone</strong></span> was designed so that it could
- sign a zone partially, using only a subset of the DNSSEC keys
- needed to produce a fully-signed zone. This permits a zone
- administrator, for example, to sign a zone with one key on one
- machine, move the resulting partially-signed zone to a second
- machine, and sign it again with a second key.
- </p>
-<p>
- An unfortunate side-effect of this flexibility is that
- <span><strong class="command">dnssec-signzone</strong></span> does not check to make sure
- it's signing a zone with any valid keys at all. An attempt to
- sign a zone without any keys will appear to succeed, producing
- a "signed" zone with no signatures. There is no warning issued
- when a zone is not fully signed.
- </p>
-<p>
- This will be corrected in a future release. In the meantime, ISC
- recommends examining the output of <span><strong class="command">dnssec-signzone</strong></span>
- to confirm that the zone is properly signed by all keys before
- using it.
- </p>
-</div>
-<div class="refsect1" lang="en">
-<a name="id2544716"></a><h2>SEE ALSO</h2>
+<a name="id2545019"></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="id2544741"></a><h2>AUTHOR</h2>
+<a name="id2545044"></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 81120e3..da6b0b2 100644
--- a/contrib/bind9/bin/dnssec/dnssectool.c
+++ b/contrib/bind9/bin/dnssec/dnssectool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssectool.c,v 1.45.334.5 2009-06-22 05:05:00 marka Exp $ */
+/* $Id: dnssectool.c,v 1.60 2010-01-19 23:48:56 tbox Exp $ */
/*! \file */
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <isc/buffer.h>
+#include <isc/dir.h>
#include <isc/entropy.h>
#include <isc/list.h>
#include <isc/mem.h>
@@ -36,6 +37,8 @@
#include <isc/util.h>
#include <isc/print.h>
+#include <dns/dnssec.h>
+#include <dns/keyvalues.h>
#include <dns/log.h>
#include <dns/name.h>
#include <dns/rdatastruct.h>
@@ -111,39 +114,16 @@ type_format(const dns_rdatatype_t type, char *cp, unsigned int size) {
}
void
-alg_format(const dns_secalg_t alg, char *cp, unsigned int size) {
- isc_buffer_t b;
- isc_region_t r;
- isc_result_t result;
-
- isc_buffer_init(&b, cp, size - 1);
- result = dns_secalg_totext(alg, &b);
- check_result(result, "dns_secalg_totext()");
- isc_buffer_usedregion(&b, &r);
- r.base[r.length] = 0;
-}
-
-void
sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size) {
char namestr[DNS_NAME_FORMATSIZE];
char algstr[DNS_NAME_FORMATSIZE];
dns_name_format(&sig->signer, namestr, sizeof(namestr));
- alg_format(sig->algorithm, algstr, sizeof(algstr));
+ dns_secalg_format(sig->algorithm, algstr, sizeof(algstr));
snprintf(cp, size, "%s/%s/%d", namestr, algstr, sig->keyid);
}
void
-key_format(const dst_key_t *key, char *cp, unsigned int size) {
- char namestr[DNS_NAME_FORMATSIZE];
- char algstr[DNS_NAME_FORMATSIZE];
-
- dns_name_format(dst_key_name(key), namestr, sizeof(namestr));
- alg_format((dns_secalg_t) dst_key_alg(key), algstr, sizeof(algstr));
- snprintf(cp, size, "%s/%s/%d", namestr, algstr, dst_key_id(key));
-}
-
-void
setup_logging(int verbose, isc_mem_t *mctx, isc_log_t **logp) {
isc_result_t result;
isc_logdestination_t destination;
@@ -265,32 +245,92 @@ cleanup_entropy(isc_entropy_t **ectx) {
isc_entropy_detach(ectx);
}
+static isc_stdtime_t
+time_units(isc_stdtime_t offset, char *suffix, const char *str) {
+ switch (suffix[0]) {
+ case 'Y': case 'y':
+ return (offset * (365 * 24 * 3600));
+ case 'M': case 'm':
+ switch (suffix[1]) {
+ case 'O': case 'o':
+ return (offset * (30 * 24 * 3600));
+ case 'I': case 'i':
+ return (offset * 60);
+ case '\0':
+ fatal("'%s' ambiguous: use 'mi' for minutes "
+ "or 'mo' for months", str);
+ default:
+ fatal("time value %s is invalid", str);
+ }
+ /* NOTREACHED */
+ break;
+ case 'W': case 'w':
+ return (offset * (7 * 24 * 3600));
+ case 'D': case 'd':
+ return (offset * (24 * 3600));
+ case 'H': case 'h':
+ return (offset * 3600);
+ case 'S': case 's': case '\0':
+ return (offset);
+ default:
+ fatal("time value %s is invalid", str);
+ }
+ /* NOTREACHED */
+ return(0); /* silence compiler warning */
+}
+
+dns_ttl_t
+strtottl(const char *str) {
+ const char *orig = str;
+ dns_ttl_t ttl;
+ char *endp;
+
+ ttl = strtol(str, &endp, 0);
+ if (ttl == 0 && endp == str)
+ fatal("TTL must be numeric");
+ ttl = time_units(ttl, endp, orig);
+ return (ttl);
+}
+
isc_stdtime_t
strtotime(const char *str, isc_int64_t now, isc_int64_t base) {
isc_int64_t val, offset;
isc_result_t result;
+ const char *orig = str;
char *endp;
- if (str[0] == '+') {
+ if ((str[0] == '0' || str[0] == '-') && str[1] == '\0')
+ return ((isc_stdtime_t) 0);
+
+ if (strncmp(str, "now", 3) == 0) {
+ base = now;
+ str += 3;
+ }
+
+ if (str[0] == '\0')
+ return ((isc_stdtime_t) base);
+ else if (str[0] == '+') {
offset = strtol(str + 1, &endp, 0);
- if (*endp != '\0')
- fatal("time value %s is invalid", str);
+ offset = time_units((isc_stdtime_t) offset, endp, orig);
val = base + offset;
- } else if (strncmp(str, "now+", 4) == 0) {
- offset = strtol(str + 4, &endp, 0);
- if (*endp != '\0')
- fatal("time value %s is invalid", str);
- val = now + offset;
+ } else if (str[0] == '-') {
+ offset = strtol(str + 1, &endp, 0);
+ offset = time_units((isc_stdtime_t) offset, endp, orig);
+ val = base - offset;
} else if (strlen(str) == 8U) {
char timestr[15];
sprintf(timestr, "%s000000", str);
result = dns_time64_fromtext(timestr, &val);
if (result != ISC_R_SUCCESS)
- fatal("time value %s is invalid", str);
+ fatal("time value %s is invalid: %s", orig,
+ isc_result_totext(result));
+ } else if (strlen(str) > 14U) {
+ fatal("time value %s is invalid", orig);
} else {
result = dns_time64_fromtext(str, &val);
if (result != ISC_R_SUCCESS)
- fatal("time value %s is invalid", str);
+ fatal("time value %s is invalid: %s", orig,
+ isc_result_totext(result));
}
return ((isc_stdtime_t) val);
@@ -311,3 +351,114 @@ strtoclass(const char *str) {
fatal("unknown class %s", str);
return (rdclass);
}
+
+isc_result_t
+try_dir(const char *dirname) {
+ isc_result_t result;
+ isc_dir_t d;
+
+ isc_dir_init(&d);
+ result = isc_dir_open(&d, dirname);
+ if (result == ISC_R_SUCCESS) {
+ isc_dir_close(&d);
+ }
+ return (result);
+}
+
+/*
+ * Check private key version compatibility.
+ */
+void
+check_keyversion(dst_key_t *key, char *keystr) {
+ int major, minor;
+ dst_key_getprivateformat(key, &major, &minor);
+ INSIST(major <= DST_MAJOR_VERSION); /* invalid private key */
+
+ if (major < DST_MAJOR_VERSION || minor < DST_MINOR_VERSION)
+ fatal("Key %s has incompatible format version %d.%d, "
+ "use -f to force upgrade to new version.",
+ keystr, major, minor);
+ if (minor > DST_MINOR_VERSION)
+ fatal("Key %s has incompatible format version %d.%d, "
+ "use -f to force downgrade to current version.",
+ keystr, major, minor);
+}
+
+void
+set_keyversion(dst_key_t *key) {
+ int major, minor;
+ dst_key_getprivateformat(key, &major, &minor);
+ INSIST(major <= DST_MAJOR_VERSION);
+
+ if (major != DST_MAJOR_VERSION || minor != DST_MINOR_VERSION)
+ dst_key_setprivateformat(key, DST_MAJOR_VERSION,
+ DST_MINOR_VERSION);
+
+ /*
+ * If the key is from a version older than 1.3, set
+ * set the creation date
+ */
+ if (major < 1 || (major == 1 && minor <= 2)) {
+ isc_stdtime_t now;
+ isc_stdtime_get(&now);
+ dst_key_settime(key, DST_TIME_CREATED, now);
+ }
+}
+
+isc_boolean_t
+key_collision(isc_uint16_t id, dns_name_t *name, const char *dir,
+ dns_secalg_t alg, isc_mem_t *mctx, isc_boolean_t *exact)
+{
+ isc_result_t result;
+ isc_boolean_t conflict = ISC_FALSE;
+ dns_dnsseckeylist_t matchkeys;
+ dns_dnsseckey_t *key = NULL;
+ isc_uint16_t oldid, diff;
+ isc_uint16_t bits = DNS_KEYFLAG_REVOKE; /* flag bits to look for */
+
+ if (exact != NULL)
+ *exact = ISC_FALSE;
+
+ ISC_LIST_INIT(matchkeys);
+ result = dns_dnssec_findmatchingkeys(name, dir, mctx, &matchkeys);
+ if (result == ISC_R_NOTFOUND)
+ return (ISC_FALSE);
+
+ while (!ISC_LIST_EMPTY(matchkeys) && !conflict) {
+ key = ISC_LIST_HEAD(matchkeys);
+ if (dst_key_alg(key->key) != alg)
+ goto next;
+
+ oldid = dst_key_id(key->key);
+ diff = (oldid > id) ? (oldid - id) : (id - oldid);
+ if ((diff & ~bits) == 0) {
+ conflict = ISC_TRUE;
+ if (diff != 0) {
+ if (verbose > 1)
+ fprintf(stderr, "Key ID %d could "
+ "collide with %d\n",
+ id, oldid);
+ } else {
+ if (exact != NULL)
+ *exact = ISC_TRUE;
+ if (verbose > 1)
+ fprintf(stderr, "Key ID %d exists\n",
+ id);
+ }
+ }
+
+ next:
+ ISC_LIST_UNLINK(matchkeys, key, link);
+ dns_dnsseckey_destroy(mctx, &key);
+ }
+
+ /* Finish freeing the list */
+ while (!ISC_LIST_EMPTY(matchkeys)) {
+ key = ISC_LIST_HEAD(matchkeys);
+ ISC_LIST_UNLINK(matchkeys, key, link);
+ dns_dnsseckey_destroy(mctx, &key);
+ }
+
+ return (conflict);
+}
+
diff --git a/contrib/bind9/bin/dnssec/dnssectool.h b/contrib/bind9/bin/dnssec/dnssectool.h
index 8cc133d..b52bc13 100644
--- a/contrib/bind9/bin/dnssec/dnssectool.h
+++ b/contrib/bind9/bin/dnssec/dnssectool.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssectool.h,v 1.22.48.2 2009-09-04 23:46:58 tbox Exp $ */
+/* $Id: dnssectool.h,v 1.31 2010-01-19 23:48:56 tbox Exp $ */
#ifndef DNSSECTOOL_H
#define DNSSECTOOL_H 1
@@ -27,8 +27,9 @@
typedef void (fatalcallback_t)(void);
-void
-fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
+ISC_PLATFORM_NORETURN_PRE void
+fatal(const char *format, ...)
+ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
void
setfatalcallback(fatalcallback_t *callback);
@@ -44,16 +45,8 @@ type_format(const dns_rdatatype_t type, char *cp, unsigned int size);
#define TYPE_FORMATSIZE 20
void
-alg_format(const dns_secalg_t alg, char *cp, unsigned int size);
-#define ALG_FORMATSIZE 20
-
-void
sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size);
-#define SIG_FORMATSIZE (DNS_NAME_FORMATSIZE + ALG_FORMATSIZE + sizeof("65535"))
-
-void
-key_format(const dst_key_t *key, char *cp, unsigned int size);
-#define KEY_FORMATSIZE (DNS_NAME_FORMATSIZE + ALG_FORMATSIZE + sizeof("65535"))
+#define SIG_FORMATSIZE (DNS_NAME_FORMATSIZE + DNS_SECALG_FORMATSIZE + sizeof("65535"))
void
setup_logging(int verbose, isc_mem_t *mctx, isc_log_t **logp);
@@ -67,10 +60,24 @@ setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx);
void
cleanup_entropy(isc_entropy_t **ectx);
+dns_ttl_t strtottl(const char *str);
+
isc_stdtime_t
strtotime(const char *str, isc_int64_t now, isc_int64_t base);
dns_rdataclass_t
strtoclass(const char *str);
+isc_result_t
+try_dir(const char *dirname);
+
+void
+check_keyversion(dst_key_t *key, char *keystr);
+
+void
+set_keyversion(dst_key_t *key);
+
+isc_boolean_t
+key_collision(isc_uint16_t id, dns_name_t *name, const char *dir,
+ dns_secalg_t alg, isc_mem_t *mctx, isc_boolean_t *exact);
#endif /* DNSSEC_DNSSECTOOL_H */
OpenPOWER on IntegriCloud