Commit 796a6c4e authored by Tony Finch's avatar Tony Finch Committed by Evan Hunt

Deprecate SHA-1 in `dnssec-dsfromkey`

This makes the `-12a` options to `dnssec-dsfromkey` work more like
`dnssec-cds`, in that you can specify more than one digest and you
will get multiple records. (Previously you could only get one
non-default digest type at a time.)

The default is now `-2`. You can get the old behaviour with `-12`.

Tests and tools that use `dnssec-dsfromkey` have been updated to use
`-12` where necessary.

This is for conformance with the DS/CDS algorithm requirements in
https://tools.ietf.org/html/draft-ietf-dnsop-algorithm-update
parent a177b07d
......@@ -75,12 +75,6 @@ static dns_fixedname_t fixed;
static dns_name_t *name = NULL;
static dns_rdataclass_t rdclass = dns_rdataclass_in;
/*
* List of digest types used by ds_from_cdnskey(), filled in by add_dtype()
* from -a arguments. The size of the array is an arbitrary limit.
*/
static dns_dsdigest_t dtype[8];
static const char *startstr = NULL; /* from which we derive notbefore */
static isc_stdtime_t notbefore = 0; /* restrict sig inception times */
static dns_rdata_rrsig_t oldestsig; /* for recording inception time */
......@@ -831,34 +825,6 @@ ds_from_cdnskey(dns_rdatalist_t *dslist, isc_buffer_t *buf,
return (ISC_R_SUCCESS);
}
/*
* For sorting the digest types so that DS records generated
* from CDNSKEY records are in canonical order.
*/
static int
cmp_dtype(const void *ap, const void *bp) {
int a = *(const dns_dsdigest_t *)ap;
int b = *(const dns_dsdigest_t *)bp;
return (a - b);
}
static void
add_dtype(const char *dn) {
dns_dsdigest_t dt;
unsigned i, n;
dt = strtodsdigest(dn);
n = sizeof(dtype)/sizeof(dtype[0]);
for (i = 0; i < n; i++) {
if (dtype[i] == 0 || dtype[i] == dt) {
dtype[i] = dt;
qsort(dtype, i+1, 1, cmp_dtype);
return;
}
}
fatal("too many -a digest type arguments");
}
static void
make_new_ds_set(ds_maker_func_t *ds_from_rdata,
uint32_t ttl, dns_rdataset_t *rdset)
......@@ -1147,7 +1113,7 @@ main(int argc, char *argv[]) {
while ((ch = isc_commandline_parse(argc, argv, OPTIONS)) != -1) {
switch (ch) {
case 'a':
add_dtype(isc_commandline_argument);
add_dtype(strtodsdigest(isc_commandline_argument));
break;
case 'c':
rdclass = strtoclass(isc_commandline_argument);
......
......@@ -228,7 +228,7 @@ logkey(dns_rdata_t *rdata)
}
static void
emit(dns_dsdigest_t dtype, bool showall, char *lookaside,
emit(dns_dsdigest_t dt, bool showall, char *lookaside,
bool cds, dns_rdata_t *rdata)
{
isc_result_t result;
......@@ -254,7 +254,7 @@ emit(dns_dsdigest_t dtype, bool showall, char *lookaside,
if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 && !showall)
return;
result = dns_ds_buildrdata(name, rdata, dtype, buf, &ds);
result = dns_ds_buildrdata(name, rdata, dt, buf, &ds);
if (result != ISC_R_SUCCESS)
fatal("can't build record");
......@@ -305,6 +305,18 @@ emit(dns_dsdigest_t dtype, bool showall, char *lookaside,
printf("%.*s\n", (int)r.length, r.base);
}
static void
emits(bool showall, char *lookaside, bool cds, dns_rdata_t *rdata) {
unsigned i, n;
n = sizeof(dtype)/sizeof(dtype[0]);
for (i = 0; i < n; i++) {
if (dtype[i] != 0) {
emit(dtype[i], showall, lookaside, cds, rdata);
}
}
}
ISC_PLATFORM_NORETURN_PRE static void
usage(void) ISC_PLATFORM_NORETURN_POST;
......@@ -343,11 +355,9 @@ main(int argc, char **argv) {
char *lookaside = NULL;
char *endp;
int ch;
dns_dsdigest_t dtype = DNS_DSDIGEST_SHA1;
bool cds = false;
bool both = true;
bool usekeyset = false;
bool showall = false;
bool cds = false;
bool usekeyset = false;
bool showall = false;
isc_result_t result;
isc_log_t *log = NULL;
dns_rdataset_t rdataset;
......@@ -355,12 +365,14 @@ main(int argc, char **argv) {
dns_rdata_init(&rdata);
if (argc == 1)
if (argc == 1) {
usage();
}
result = isc_mem_create(0, 0, &mctx);
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS) {
fatal("out of memory");
}
#if USE_PKCS11
pk11_result_register();
......@@ -373,19 +385,16 @@ main(int argc, char **argv) {
while ((ch = isc_commandline_parse(argc, argv, OPTIONS)) != -1) {
switch (ch) {
case '1':
dtype = DNS_DSDIGEST_SHA1;
both = false;
add_dtype(DNS_DSDIGEST_SHA1);
break;
case '2':
dtype = DNS_DSDIGEST_SHA256;
both = false;
add_dtype(DNS_DSDIGEST_SHA256);
break;
case 'A':
showall = true;
break;
case 'a':
dtype = strtodsdigest(isc_commandline_argument);
both = false;
add_dtype(strtodsdigest(isc_commandline_argument));
break;
case 'C':
if (lookaside != NULL)
......@@ -453,22 +462,32 @@ main(int argc, char **argv) {
rdclass = strtoclass(classname);
if (usekeyset && filename != NULL)
if (usekeyset && filename != NULL) {
fatal("cannot use both -s and -f");
}
/* When not using -f, -A is implicit */
if (filename == NULL)
if (filename == NULL) {
showall = true;
}
if (argc < isc_commandline_index + 1 && filename == NULL)
/* Default digest type if none specified. */
if (dtype[0] == 0) {
dtype[0] = DNS_DSDIGEST_SHA256;
}
if (argc < isc_commandline_index + 1 && filename == NULL) {
fatal("the key file name was not specified");
if (argc > isc_commandline_index + 1)
}
if (argc > isc_commandline_index + 1) {
fatal("extraneous arguments");
}
result = dst_lib_init(mctx, NULL);
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS) {
fatal("could not initialize dst: %s",
isc_result_totext(result));
}
setup_logging(mctx, &log);
......@@ -478,38 +497,38 @@ main(int argc, char **argv) {
if (argc < isc_commandline_index + 1 && filename != NULL) {
/* using zone name as the zone file name */
namestr = filename;
} else
} else {
namestr = argv[isc_commandline_index];
}
result = initname(namestr);
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS) {
fatal("could not initialize name %s", namestr);
}
if (usekeyset)
if (usekeyset) {
result = loadkeyset(dir, &rdataset);
else
} else {
result = loadset(filename, &rdataset);
}
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS) {
fatal("could not load DNSKEY set: %s\n",
isc_result_totext(result));
}
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) {
result = dns_rdataset_next(&rdataset))
{
dns_rdata_init(&rdata);
dns_rdataset_current(&rdataset, &rdata);
if (verbose > 2)
if (verbose > 2) {
logkey(&rdata);
}
if (both) {
emit(DNS_DSDIGEST_SHA1, showall, lookaside,
cds, &rdata);
emit(DNS_DSDIGEST_SHA256, showall, lookaside,
cds, &rdata);
} else
emit(dtype, showall, lookaside, cds, &rdata);
emits(showall, lookaside, cds, &rdata);
}
} else {
unsigned char key_buf[DST_KEY_MAXSIZE];
......@@ -517,28 +536,25 @@ main(int argc, char **argv) {
loadkey(argv[isc_commandline_index], key_buf,
DST_KEY_MAXSIZE, &rdata);
if (both) {
emit(DNS_DSDIGEST_SHA1, showall, lookaside, cds,
&rdata);
emit(DNS_DSDIGEST_SHA256, showall, lookaside, cds,
&rdata);
} else
emit(dtype, showall, lookaside, cds, &rdata);
emits(showall, lookaside, cds, &rdata);
}
if (dns_rdataset_isassociated(&rdataset))
if (dns_rdataset_isassociated(&rdataset)) {
dns_rdataset_disassociate(&rdataset);
}
cleanup_logging(&log);
dst_lib_destroy();
dns_name_destroy();
if (verbose > 10)
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
} else {
return (0);
}
}
......@@ -12,7 +12,7 @@
<!-- Converted by db4-upgrade version 1.0 -->
<refentry xmlns:db="http://docbook.org/ns/docbook" version="5.0" xml:id="man.dnssec-dsfromkey">
<info>
<date>2012-05-02</date>
<date>2019-05-08</date>
</info>
<refentryinfo>
<corpname>ISC</corpname>
......@@ -150,7 +150,9 @@
<term>-1</term>
<listitem>
<para>
An abbreviation for <option>-a SHA1</option>
An abbreviation for <option>-a SHA-1</option>.
(Note: The SHA-1 algorithm is no longer recommended for use
when generating new DS and CDS records.)
</para>
</listitem>
</varlistentry>
......@@ -159,7 +161,7 @@
<term>-2</term>
<listitem>
<para>
An abbreviation for <option>-a SHA-256</option>
An abbreviation for <option>-a SHA-256</option>.
</para>
</listitem>
</varlistentry>
......@@ -178,6 +180,8 @@
SHA-1, SHA-256, or SHA-384. These values are case insensitive,
and the hyphen may be omitted. If no algorithm is specified,
the default is SHA-256.
(Note: The SHA-1 algorithm is no longer recommended for use
when generating new DS and CDS records.)
</para>
</listitem>
</varlistentry>
......
......@@ -58,6 +58,7 @@
#include "dnssectool.h"
int verbose;
uint8_t dtype[8];
static fatalcallback_t *fatalcallback = NULL;
......@@ -343,6 +344,32 @@ strtodsdigest(const char *algname) {
}
}
static int
cmp_dtype(const void *ap, const void *bp) {
int a = *(const uint8_t *)ap;
int b = *(const uint8_t *)bp;
return (a - b);
}
void
add_dtype(unsigned int dt) {
unsigned i, n;
/* ensure there is space for a zero terminator */
n = sizeof(dtype)/sizeof(dtype[0]) - 1;
for (i = 0; i < n; i++) {
if (dtype[i] == dt) {
return;
}
if (dtype[i] == 0) {
dtype[i] = dt;
qsort(dtype, i+1, 1, cmp_dtype);
return;
}
}
fatal("too many -a digest type arguments");
}
isc_result_t
try_dir(const char *dirname) {
isc_result_t result;
......
......@@ -31,6 +31,15 @@ extern int verbose;
/*! program name, statically initialized in each program */
extern const char *program;
/*!
* List of DS digest types used by dnssec-cds and dnssec-dsfromkey,
* defined in dnssectool.c. Filled in by add_dtype() from -a
* arguments, sorted (so that DS records are in a canonical order) and
* terminated by a zero. The size of the array is an arbitrary limit
* which should be greater than the number of known digest types.
*/
extern uint8_t dtype[8];
typedef void (fatalcallback_t)(void);
ISC_PLATFORM_NORETURN_PRE void
......@@ -65,11 +74,14 @@ isc_stdtime_t
strtotime(const char *str, int64_t now, int64_t base,
bool *setp);
dns_rdataclass_t
strtoclass(const char *str);
unsigned int
strtodsdigest(const char *str);
dns_rdataclass_t
strtoclass(const char *str);
void
add_dtype(unsigned int dt);
isc_result_t
try_dir(const char *dirname);
......
......@@ -115,7 +115,7 @@ def check(zone, args):
klist = []
if args.masterfile:
cmd = [args.dsfromkey, "-f", args.masterfile]
cmd = [args.dsfromkey, "-12f", args.masterfile]
if args.lookaside:
cmd += ["-l", args.lookaside]
cmd.append(zone)
......@@ -123,7 +123,7 @@ def check(zone, args):
else:
intods, _ = Popen([args.dig, "+noall", "+answer", "-t", "dnskey",
"-q", zone], stdout=PIPE).communicate()
cmd = [args.dsfromkey, "-f", "-"]
cmd = [args.dsfromkey, "-12f", "-"]
if args.lookaside:
cmd += ["-l", args.lookaside]
cmd.append(zone)
......
......@@ -44,7 +44,7 @@ tac() {
convert() {
key=$1
n=$2
$DSFROMKEY $key >DS.$n
$DSFROMKEY -12 $key >DS.$n
grep ' 8 1 ' DS.$n >DS.$n-1
grep ' 8 2 ' DS.$n >DS.$n-2
sed 's/ IN DS / IN CDS /' <DS.$n >>CDS.$n
......
......@@ -2752,7 +2752,7 @@ status=$((status+ret))
echo_i "check dnssec-dsfromkey from stdin ($n)"
ret=0
dig_with_opts dnskey algroll. @10.53.0.2 | \
$DSFROMKEY -f - algroll. > dig.out.ns2.test$n || ret=1
$DSFROMKEY -12 -f - algroll. > dig.out.ns2.test$n || ret=1
NF=$(awk '{print NF}' dig.out.ns2.test$n | sort -u)
[ "${NF}" = 7 ] || ret=1
# make canonical
......@@ -3337,7 +3337,7 @@ echo update delete cds-update.secure CDS
echo send
dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure |
grep "DNSKEY.257" |
$DSFROMKEY -C -f - -T 1 cds-update.secure |
$DSFROMKEY -12 -C -f - -T 1 cds-update.secure |
sed "s/^/update add /"
echo send
) | $NSUPDATE
......@@ -3360,7 +3360,7 @@ echo update delete cds-kskonly.secure CDS
echo send
dig_with_opts +noall +answer @10.53.0.2 dnskey cds-kskonly.secure |
grep "DNSKEY.257" |
$DSFROMKEY -C -f - -T 1 cds-kskonly.secure |
$DSFROMKEY -12 -C -f - -T 1 cds-kskonly.secure |
sed "s/^/update add /"
echo send
) | $NSUPDATE
......@@ -3394,11 +3394,11 @@ echo update delete cds-update.secure CDS
echo send
dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure |
grep "DNSKEY.257" |
$DSFROMKEY -C -f - -T 1 cds-update.secure |
$DSFROMKEY -12 -C -f - -T 1 cds-update.secure |
sed "s/^/update add /"
dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure |
grep "DNSKEY.257" | sed 's/DNSKEY.257/DNSKEY 258/' |
$DSFROMKEY -C -A -f - -T 1 cds-update.secure |
$DSFROMKEY -12 -C -A -f - -T 1 cds-update.secure |
sed "s/^/update add /"
echo send
) | $NSUPDATE
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment