Commit 582f8b9a authored by Mark Andrews's avatar Mark Andrews

2488. [func] Added a tool, dnssec-dsfromkey, to generate DS records

                        from keyset and .key files. [RT #18694]
parent 18fa75b6
2488. [func] Added a tool, dnssec-dsfromkey, to generate DS records
from keyset and .key files. [RT #18694]
2487. [bug] Give TCP connections longer to complete. [RT #18675]
2486. [func] The default locations for named.pid and lwresd.pid
......
......@@ -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.34 2008/04/01 23:47:10 tbox Exp $
# $Id: Makefile.in,v 1.35 2008/11/07 02:28:49 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
......@@ -40,22 +40,27 @@ LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
# Alphabetically
TARGETS = dnssec-keygen@EXEEXT@ dnssec-signzone@EXEEXT@ \
dnssec-keyfromlabel@EXEEXT@
dnssec-keyfromlabel@EXEEXT@ dnssec-dsfromkey@EXEEXT@
OBJS = dnssectool.@O@
SRCS = dnssec-keyfromlabel.c 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-keyfromlabel.8 dnssec-keygen.8 dnssec-signzone.8
MANPAGES = dnssec-dsfromkey.8 dnssec-keyfromlabel.8 dnssec-keygen.8 \
dnssec-signzone.8
HTMLPAGES = dnssec-keyfromlabel.html 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}
......
.\" 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-dsfromkey.8,v 1.2 2008/11/07 02:28:49 marka Exp $
.\"
.hy 0
.ad l
.\" Title: dnssec-dsfromkey
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.73.2 <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 DS RR for the given key(s) as defined in RFC 3658 and RFC 4509\.
.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\.
.PP
The keyset file name is built from the
\fBdirectory\fR, the string
\fIkeyset\-\fR
and the
\fBdnsname\fR
with a trailing dot\.
.SH "CAVEAT"
.PP
A keyfile error can give a "file not found" even 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
/*
* 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.c,v 1.2 2008/11/07 02:28:49 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, dns_rdata_t *rdata)
{
isc_result_t result;
dst_key_t *key = NULL;
unsigned char key_buf[DST_KEY_MAXSIZE];
isc_buffer_t keyb;
isc_region_t r;
dns_rdataset_init(&keyset);
dns_rdata_init(rdata);
isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
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 {
loadkey(argv[isc_commandline_index], &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);
return (0);
}
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- $Id: dnssec-dsfromkey.docbook,v 1.2 2008/11/07 02:28:49 marka 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>