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