From 42ed7e43dcf3e5bed10b5476b6d96f0c5d4ac1ee Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 12 Mar 2019 16:09:01 +1100 Subject: [PATCH 1/7] tests/resolver: look for hash algorithm 2 (SHA-256) now --- bin/tests/system/resolver/tests.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh index 3d32e31ad6..6706e65675 100755 --- a/bin/tests/system/resolver/tests.sh +++ b/bin/tests/system/resolver/tests.sh @@ -470,16 +470,16 @@ n=`expr $n + 1` echo_i "check prefetch of validated DS's RRSIG TTL is updated (${n})" ret=0 $DIG $DIGOPTS +dnssec @10.53.0.5 ds.example.net ds > dig.out.1.${n} || ret=1 -ttl1=`awk '$4 == "DS" && $7 == "1" { print $2 - 2 }' dig.out.1.${n}` +ttl1=`awk '$4 == "DS" && $7 == "2" { print $2 - 2 }' dig.out.1.${n}` # sleep so we are in prefetch range sleep ${ttl1:-0} # trigger prefetch $DIG $DIGOPTS @10.53.0.5 ds.example.net ds > dig.out.2.${n} || ret=1 -ttl1=`awk '$4 == "DS" && $7 == "1" { print $2 }' dig.out.2.${n}` +ttl1=`awk '$4 == "DS" && $7 == "2" { print $2 }' dig.out.2.${n}` sleep 1 # check that prefetch occured $DIG $DIGOPTS @10.53.0.5 ds.example.net ds +dnssec > dig.out.3.${n} || ret=1 -dsttl=`awk '$4 == "DS" && $7 == "1" { print $2 }' dig.out.3.${n}` +dsttl=`awk '$4 == "DS" && $7 == "2" { print $2 }' dig.out.3.${n}` sigttl=`awk '$4 == "RRSIG" && $5 == "DS" { print $2 }' dig.out.3.${n}` test ${dsttl:-0} -gt ${ttl2:-1} || ret=1 test ${sigttl:-0} -gt ${ttl2:-1} || ret=1 From a177b07da1d321841027660180901885461103e6 Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Tue, 29 Jan 2019 16:43:54 +0000 Subject: [PATCH 2/7] bin/dnssec: move a little boilerplate into shared code --- bin/dnssec/dnssec-cds.c | 5 ----- bin/dnssec/dnssec-dsfromkey.c | 5 ----- bin/dnssec/dnssec-importkey.c | 5 ----- bin/dnssec/dnssec-keyfromlabel.c | 1 - bin/dnssec/dnssec-keygen.c | 1 - bin/dnssec/dnssec-revoke.c | 1 - bin/dnssec/dnssec-settime.c | 1 - bin/dnssec/dnssec-signzone.c | 5 ----- bin/dnssec/dnssec-verify.c | 1 - bin/dnssec/dnssectool.c | 3 +-- bin/dnssec/dnssectool.h | 10 ++++++++++ 11 files changed, 11 insertions(+), 27 deletions(-) diff --git a/bin/dnssec/dnssec-cds.c b/bin/dnssec/dnssec-cds.c index dfbc327aff..198ebcf959 100644 --- a/bin/dnssec/dnssec-cds.c +++ b/bin/dnssec/dnssec-cds.c @@ -59,12 +59,7 @@ #include "dnssectool.h" -#ifndef PATH_MAX -#define PATH_MAX 1024 /* WIN32, and others don't define this. */ -#endif - const char *program = "dnssec-cds"; -int verbose; /* * Infrastructure diff --git a/bin/dnssec/dnssec-dsfromkey.c b/bin/dnssec/dnssec-dsfromkey.c index 8aecb5f477..1fdded5ebb 100644 --- a/bin/dnssec/dnssec-dsfromkey.c +++ b/bin/dnssec/dnssec-dsfromkey.c @@ -47,12 +47,7 @@ #include "dnssectool.h" -#ifndef PATH_MAX -#define PATH_MAX 1024 /* WIN32, and others don't define this. */ -#endif - const char *program = "dnssec-dsfromkey"; -int verbose; static dns_rdataclass_t rdclass; static dns_fixedname_t fixed; diff --git a/bin/dnssec/dnssec-importkey.c b/bin/dnssec/dnssec-importkey.c index 195909f9ce..494535bd10 100644 --- a/bin/dnssec/dnssec-importkey.c +++ b/bin/dnssec/dnssec-importkey.c @@ -46,12 +46,7 @@ #include "dnssectool.h" -#ifndef PATH_MAX -#define PATH_MAX 1024 /* WIN32, and others don't define this. */ -#endif - const char *program = "dnssec-importkey"; -int verbose; static dns_rdataclass_t rdclass; static dns_fixedname_t fixed; diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c index 741c047450..ea156c7677 100644 --- a/bin/dnssec/dnssec-keyfromlabel.c +++ b/bin/dnssec/dnssec-keyfromlabel.c @@ -46,7 +46,6 @@ #define MAX_RSA 4096 /* should be long enough... */ const char *program = "dnssec-keyfromlabel"; -int verbose; ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index 203f1507a7..aae310341d 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -61,7 +61,6 @@ #define MAX_RSA 4096 /* should be long enough... */ const char *program = "dnssec-keygen"; -int verbose; ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; diff --git a/bin/dnssec/dnssec-revoke.c b/bin/dnssec/dnssec-revoke.c index 17f158397a..6c8f38b5d7 100644 --- a/bin/dnssec/dnssec-revoke.c +++ b/bin/dnssec/dnssec-revoke.c @@ -37,7 +37,6 @@ #include "dnssectool.h" const char *program = "dnssec-revoke"; -int verbose; static isc_mem_t *mctx = NULL; diff --git a/bin/dnssec/dnssec-settime.c b/bin/dnssec/dnssec-settime.c index ff49aea0be..f362162be3 100644 --- a/bin/dnssec/dnssec-settime.c +++ b/bin/dnssec/dnssec-settime.c @@ -40,7 +40,6 @@ #include "dnssectool.h" const char *program = "dnssec-settime"; -int verbose; static isc_mem_t *mctx = NULL; diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index da3bfb3031..9530bfe4e6 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -86,12 +86,7 @@ #include "dnssectool.h" -#ifndef PATH_MAX -#define PATH_MAX 1024 /* WIN32, and others don't define this. */ -#endif - const char *program = "dnssec-signzone"; -int verbose; typedef struct hashlist hashlist_t; diff --git a/bin/dnssec/dnssec-verify.c b/bin/dnssec/dnssec-verify.c index 2d14eb0660..b38368b2df 100644 --- a/bin/dnssec/dnssec-verify.c +++ b/bin/dnssec/dnssec-verify.c @@ -67,7 +67,6 @@ #include "dnssectool.h" const char *program = "dnssec-verify"; -int verbose; static isc_stdtime_t now; static isc_mem_t *mctx = NULL; diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c index 81d9cc04d9..5cfd8e74d6 100644 --- a/bin/dnssec/dnssectool.c +++ b/bin/dnssec/dnssectool.c @@ -57,8 +57,7 @@ #include "dnssectool.h" -extern int verbose; -extern const char *program; +int verbose; static fatalcallback_t *fatalcallback = NULL; diff --git a/bin/dnssec/dnssectool.h b/bin/dnssec/dnssectool.h index aeae3a18b3..16533669a6 100644 --- a/bin/dnssec/dnssectool.h +++ b/bin/dnssec/dnssectool.h @@ -21,6 +21,16 @@ #include #include +#ifndef PATH_MAX +#define PATH_MAX 1024 /* WIN32, and others don't define this. */ +#endif + +/*! verbosity: set by -v option in each program, defined in dnssectool.c */ +extern int verbose; + +/*! program name, statically initialized in each program */ +extern const char *program; + typedef void (fatalcallback_t)(void); ISC_PLATFORM_NORETURN_PRE void From 796a6c4e4e5872a85289097ee1e7f5eaed16c8a6 Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Thu, 31 Jan 2019 17:05:57 +0000 Subject: [PATCH 3/7] 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 --- bin/dnssec/dnssec-cds.c | 36 +--------- bin/dnssec/dnssec-dsfromkey.c | 104 ++++++++++++++++------------ bin/dnssec/dnssec-dsfromkey.docbook | 10 ++- bin/dnssec/dnssectool.c | 27 ++++++++ bin/dnssec/dnssectool.h | 16 ++++- bin/python/isc/checkds.py.in | 4 +- bin/tests/system/cds/setup.sh | 2 +- bin/tests/system/dnssec/tests.sh | 10 +-- 8 files changed, 117 insertions(+), 92 deletions(-) diff --git a/bin/dnssec/dnssec-cds.c b/bin/dnssec/dnssec-cds.c index 198ebcf959..ba54acbd8a 100644 --- a/bin/dnssec/dnssec-cds.c +++ b/bin/dnssec/dnssec-cds.c @@ -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); diff --git a/bin/dnssec/dnssec-dsfromkey.c b/bin/dnssec/dnssec-dsfromkey.c index 1fdded5ebb..5ea294b93e 100644 --- a/bin/dnssec/dnssec-dsfromkey.c +++ b/bin/dnssec/dnssec-dsfromkey.c @@ -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); + } } diff --git a/bin/dnssec/dnssec-dsfromkey.docbook b/bin/dnssec/dnssec-dsfromkey.docbook index 7f0039ebb1..d67e404178 100644 --- a/bin/dnssec/dnssec-dsfromkey.docbook +++ b/bin/dnssec/dnssec-dsfromkey.docbook @@ -12,7 +12,7 @@ - 2012-05-02 + 2019-05-08 ISC @@ -150,7 +150,9 @@ -1 - An abbreviation for + An abbreviation for . + (Note: The SHA-1 algorithm is no longer recommended for use + when generating new DS and CDS records.) @@ -159,7 +161,7 @@ -2 - An abbreviation for + An abbreviation for . @@ -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.) diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c index 5cfd8e74d6..e1205d05f8 100644 --- a/bin/dnssec/dnssectool.c +++ b/bin/dnssec/dnssectool.c @@ -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; diff --git a/bin/dnssec/dnssectool.h b/bin/dnssec/dnssectool.h index 16533669a6..e4798e8336 100644 --- a/bin/dnssec/dnssectool.h +++ b/bin/dnssec/dnssectool.h @@ -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); diff --git a/bin/python/isc/checkds.py.in b/bin/python/isc/checkds.py.in index b5cbe3fd05..1f1963f3ae 100644 --- a/bin/python/isc/checkds.py.in +++ b/bin/python/isc/checkds.py.in @@ -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) diff --git a/bin/tests/system/cds/setup.sh b/bin/tests/system/cds/setup.sh index ca13261af5..92bd9c94d4 100644 --- a/bin/tests/system/cds/setup.sh +++ b/bin/tests/system/cds/setup.sh @@ -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 /' >CDS.$n diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 4cf69f0beb..5dc48d7cf8 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -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 From 129b731273bd9325abaaf760f6e37bb0b05f952a Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Mon, 4 Feb 2019 13:46:51 +0000 Subject: [PATCH 4/7] Deprecate SHA-1 in `dnssec-checkds` This changes the behaviour so that it explicitly lists DS records that are present in the parent but do not have keys in the child. Any inconsistency is reported as an error, which is somewhat stricter than before. This is for conformance with the DS/CDS algorithm requirements in https://tools.ietf.org/html/draft-ietf-dnsop-algorithm-update --- bin/python/dnssec-checkds.docbook | 20 +++++++++++++- bin/python/isc/checkds.py.in | 46 +++++++++++++++++-------------- bin/tests/system/checkds/tests.sh | 29 ++++++++++--------- 3 files changed, 61 insertions(+), 34 deletions(-) diff --git a/bin/python/dnssec-checkds.docbook b/bin/python/dnssec-checkds.docbook index 113e47ceb0..bc18b616f6 100644 --- a/bin/python/dnssec-checkds.docbook +++ b/bin/python/dnssec-checkds.docbook @@ -67,8 +67,26 @@ OPTIONS - + + + -a algorithm + + + Specify a digest algorithm to use when converting the + zone's DNSKEY records to expected DS or DLV records. This + option can be repeated, so that multiple records are + checked for each DNSKEY record. + + + The algorithm must be one of + 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. + + + + -f file diff --git a/bin/python/isc/checkds.py.in b/bin/python/isc/checkds.py.in index 1f1963f3ae..f20d6bf564 100644 --- a/bin/python/isc/checkds.py.in +++ b/bin/python/isc/checkds.py.in @@ -114,19 +114,19 @@ def check(zone, args): klist = [] + cmd = [args.dsfromkey] + for algo in args.algo: + cmd += ['-a', algo] + if args.lookaside: + cmd += ["-l", args.lookaside] + if args.masterfile: - cmd = [args.dsfromkey, "-12f", args.masterfile] - if args.lookaside: - cmd += ["-l", args.lookaside] - cmd.append(zone) + cmd += ["-f", args.masterfile, zone] fp, _ = Popen(cmd, stdout=PIPE).communicate() else: intods, _ = Popen([args.dig, "+noall", "+answer", "-t", "dnskey", "-q", zone], stdout=PIPE).communicate() - cmd = [args.dsfromkey, "-12f", "-"] - if args.lookaside: - cmd += ["-l", args.lookaside] - cmd.append(zone) + cmd += ["-f", "-", zone] fp, _ = Popen(cmd, stdin=PIPE, stdout=PIPE).communicate(intods) for line in fp.splitlines(): @@ -138,23 +138,27 @@ def check(zone, args): print("No DNSKEY records found in zone apex") return False - found = False + match = True + for rr in rrlist: + if rr not in klist: + print("KSK for %s %s/%03d/%05d (%s) missing from child" % + (rr.rrtype, rr.rrname.strip('.'), rr.keyalg, + rr.keyid, SECRR.hashalgs[rr.hashalg])) + match = False + for rr in klist: + if rr not in rrlist: + print("%s for KSK %s/%03d/%05d (%s) missing from parent" % + (rr.rrtype, rr.rrname.strip('.'), rr.keyalg, + rr.keyid, SECRR.hashalgs[rr.hashalg])) + match = False for rr in klist: if rr in rrlist: print("%s for KSK %s/%03d/%05d (%s) found in parent" % (rr.rrtype, rr.rrname.strip('.'), rr.keyalg, rr.keyid, SECRR.hashalgs[rr.hashalg])) - found = True - else: - print("%s for KSK %s/%03d/%05d (%s) missing from parent" % - (rr.rrtype, rr.rrname.strip('.'), rr.keyalg, - rr.keyid, SECRR.hashalgs[rr.hashalg])) - if not found: - print("No %s records were found for any DNSKEY" % - ("DLV" if args.lookaside else "DS")) + return match - return found ############################################################################ # parse_args: @@ -167,6 +171,8 @@ def parse_args(): sbindir = 'bin' if os.name == 'nt' else 'sbin' parser.add_argument('zone', type=str, help='zone to check') + parser.add_argument('-a', '--algo', dest='algo', action='append', + default=[], type=str, help='DS digest algorithm') parser.add_argument('-d', '--dig', dest='dig', default=os.path.join(prefix(bindir), 'dig'), type=str, help='path to \'dig\'') @@ -196,5 +202,5 @@ def parse_args(): ############################################################################ def main(): args = parse_args() - found = check(args.zone, args) - exit(0 if found else 1) + match = check(args.zone, args) + exit(0 if match else 1) diff --git a/bin/tests/system/checkds/tests.sh b/bin/tests/system/checkds/tests.sh index 2d2faba9cd..1d46bc53c4 100644 --- a/bin/tests/system/checkds/tests.sh +++ b/bin/tests/system/checkds/tests.sh @@ -15,10 +15,10 @@ SYSTEMTESTTOP=.. if [ "$CYGWIN" ]; then DIG=".\dig.bat" WINDSFROMKEY=`cygpath -w $DSFROMKEY` - CHECKDS="$CHECKDS -d $DIG -D $WINDSFROMKEY" + CHECKDS="$CHECKDS -a sha1 -a sha256 -d $DIG -D $WINDSFROMKEY" else DIG="./dig.sh" - CHECKDS="$CHECKDS -d $DIG -D $DSFROMKEY" + CHECKDS="$CHECKDS -a sha1 -a sha256 -d $DIG -D $DSFROMKEY" fi chmod +x $DIG @@ -61,7 +61,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` -echo_i "checking for incorrect DS, lowronging up key via 'dig' ($n)" +echo_i "checking for incorrect DS, looking up key via 'dig' ($n)" ret=0 $CHECKDS wrong.example > checkds.out.$n 2>&1 || ret=1 grep 'SHA-1' checkds.out.$n > /dev/null 2>&1 || ret=1 @@ -79,7 +79,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` -echo_i "checking for incorrect DLV, lowronging up key via 'dig' ($n)" +echo_i "checking for incorrect DLV, looking up key via 'dig' ($n)" ret=0 $CHECKDS -l dlv.example wrong.example > checkds.out.$n 2>&1 || ret=1 grep 'SHA-1' checkds.out.$n > /dev/null 2>&1 || ret=1 @@ -97,10 +97,9 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` - echo_i "checking for partially missing DS, looking up key via 'dig' ($n)" ret=0 -$CHECKDS missing.example > checkds.out.$n 2>&1 || ret=1 +$CHECKDS missing.example > checkds.out.$n 2>&1 && ret=1 grep 'SHA-1.*found' checkds.out.$n > /dev/null 2>&1 || ret=1 grep 'SHA-256.*found' checkds.out.$n > /dev/null 2>&1 || ret=1 grep 'SHA-1.*missing' checkds.out.$n > /dev/null 2>&1 || ret=1 @@ -111,7 +110,7 @@ status=`expr $status + $ret` echo_i "checking for partially missing DS, obtaining key from file ($n)" ret=0 -$CHECKDS -f missing.example.dnskey.db missing.example > checkds.out.$n 2>&1 || ret=1 +$CHECKDS -f missing.example.dnskey.db missing.example > checkds.out.$n 2>&1 && ret=1 grep 'SHA-1.*found' checkds.out.$n > /dev/null 2>&1 || ret=1 grep 'SHA-256.*found' checkds.out.$n > /dev/null 2>&1 || ret=1 grep 'SHA-1.*missing' checkds.out.$n > /dev/null 2>&1 || ret=1 @@ -122,7 +121,7 @@ status=`expr $status + $ret` echo_i "checking for partially missing DLV, looking up key via 'dig' ($n)" ret=0 -$CHECKDS -l dlv.example missing.example > checkds.out.$n 2>&1 || ret=1 +$CHECKDS -l dlv.example missing.example > checkds.out.$n 2>&1 && ret=1 grep 'SHA-1.*found' checkds.out.$n > /dev/null 2>&1 || ret=1 grep 'SHA-256.*found' checkds.out.$n > /dev/null 2>&1 || ret=1 grep 'SHA-1.*missing' checkds.out.$n > /dev/null 2>&1 || ret=1 @@ -133,7 +132,7 @@ status=`expr $status + $ret` echo_i "checking for partially missing DLV, obtaining key from file ($n)" ret=0 -$CHECKDS -l dlv.example -f missing.example.dnskey.db missing.example > checkds.out.$n 2>&1 || ret=1 +$CHECKDS -l dlv.example -f missing.example.dnskey.db missing.example > checkds.out.$n 2>&1 && ret=1 grep 'SHA-1.*found' checkds.out.$n > /dev/null 2>&1 || ret=1 grep 'SHA-256.*found' checkds.out.$n > /dev/null 2>&1 || ret=1 grep 'SHA-1.*missing' checkds.out.$n > /dev/null 2>&1 || ret=1 @@ -145,7 +144,8 @@ status=`expr $status + $ret` echo_i "checking for entirely missing DS, looking up key via 'dig' ($n)" ret=0 $CHECKDS none.example > checkds.out.$n 2>&1 && ret=1 -grep 'No DS' checkds.out.$n > /dev/null 2>&1 || ret=1 +grep 'SHA-1.*found' checkds.out.$n > /dev/null 2>&1 && ret=1 +grep 'SHA-256.*found' checkds.out.$n > /dev/null 2>&1 && ret=1 n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -153,7 +153,8 @@ status=`expr $status + $ret` echo_i "checking for entirely missing DS, obtaining key from file ($n)" ret=0 $CHECKDS -f none.example.dnskey.db none.example > checkds.out.$n 2>&1 && ret=1 -grep 'No DS' checkds.out.$n > /dev/null 2>&1 || ret=1 +grep 'SHA-1.*found' checkds.out.$n > /dev/null 2>&1 && ret=1 +grep 'SHA-256.*found' checkds.out.$n > /dev/null 2>&1 && ret=1 n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -161,7 +162,8 @@ status=`expr $status + $ret` echo_i "checking for entirely missing DLV, looking up key via 'dig' ($n)" ret=0 $CHECKDS -l dlv.example none.example > checkds.out.$n 2>&1 && ret=1 -grep 'No DLV' checkds.out.$n > /dev/null 2>&1 || ret=1 +grep 'SHA-1.*found' checkds.out.$n > /dev/null 2>&1 && ret=1 +grep 'SHA-256.*found' checkds.out.$n > /dev/null 2>&1 && ret=1 n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -169,7 +171,8 @@ status=`expr $status + $ret` echo_i "checking for entirely missing DLV, obtaining key from file ($n)" ret=0 $CHECKDS -l dlv.example -f none.example.dnskey.db none.example > checkds.out.$n 2>&1 && ret=1 -grep 'No DLV' checkds.out.$n > /dev/null 2>&1 || ret=1 +grep 'SHA-1.*found' checkds.out.$n > /dev/null 2>&1 && ret=1 +grep 'SHA-256.*found' checkds.out.$n > /dev/null 2>&1 && ret=1 n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` From d8f2eb249a729ff0a18aa348c14c3785dbb78ce2 Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Wed, 30 Jan 2019 18:04:52 +0000 Subject: [PATCH 5/7] Deprecate SHA-1 DS digests in `dnssec-signzone` This affects two cases: * When writing a `dsset` file for this zone, to be used by its parent, only write a SHA-256 DS record. * When reading a `keyset` file for a child, to generate DS records to include in this zone, generate SHA-256 DS records only. This change does not affect digests used in CDS records. This is for conformance with the DS/CDS algorithm requirements in https://tools.ietf.org/html/draft-ietf-dnsop-algorithm-update --- bin/dnssec/dnssec-signzone.c | 26 ++------------------------ bin/tests/system/dnssec/tests.sh | 2 +- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index 9530bfe4e6..f3a24cb1c3 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -987,16 +987,6 @@ loadds(dns_name_t *name, uint32_t ttl, dns_rdataset_t *dsset) { dns_rdata_init(&key); dns_rdata_init(&ds); dns_rdataset_current(&keyset, &key); - result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA1, - dsbuf, &ds); - check_result(result, "dns_ds_buildrdata"); - - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, name, - ttl, &ds, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - - dns_rdata_reset(&ds); result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA256, dsbuf, &ds); check_result(result, "dns_ds_buildrdata"); @@ -2995,19 +2985,6 @@ writeset(const char *prefix, dns_rdatatype_t type) { isc_buffer_usedregion(&b, &r); dns_rdata_fromregion(&rdata, gclass, dns_rdatatype_dnskey, &r); if (type != dns_rdatatype_dnskey) { - result = dns_ds_buildrdata(gorigin, &rdata, - DNS_DSDIGEST_SHA1, - dsbuf, &ds); - check_result(result, "dns_ds_buildrdata"); - if (type == dns_rdatatype_dlv) - ds.type = dns_rdatatype_dlv; - result = dns_difftuple_create(mctx, - DNS_DIFFOP_ADDRESIGN, - name, 0, &ds, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - - dns_rdata_reset(&ds); result = dns_ds_buildrdata(gorigin, &rdata, DNS_DSDIGEST_SHA256, dsbuf, &ds); @@ -3018,11 +2995,12 @@ writeset(const char *prefix, dns_rdatatype_t type) { DNS_DIFFOP_ADDRESIGN, name, 0, &ds, &tuple); - } else + } else { result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, gorigin, zone_soa_min_ttl, &rdata, &tuple); + } check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); } diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 5dc48d7cf8..a60c0f0696 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -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 -12 -f - algroll. > dig.out.ns2.test$n || ret=1 + $DSFROMKEY -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 From 8785f6fa3415471491fac58ca4a5fc06f0db4e30 Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Wed, 30 Jan 2019 18:25:21 +0000 Subject: [PATCH 6/7] Deprecate SHA-1 CDS records This affects CDS records generated by `named` and `dnssec-signzone` based on `-P sync` and `-D sync` key timing instructions. This is for conformance with the DS/CDS algorithm requirements in https://tools.ietf.org/html/draft-ietf-dnsop-algorithm-update --- lib/dns/dnssec.c | 75 +++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index 4dfa7276fb..b51f411dac 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -1909,8 +1909,8 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, for (key = ISC_LIST_HEAD(*keys); key != NULL; key = ISC_LIST_NEXT(key, link)) { - dns_rdata_t cdsrdata1 = DNS_RDATA_INIT; - dns_rdata_t cdsrdata2 = DNS_RDATA_INIT; + dns_rdata_t cds_sha1 = DNS_RDATA_INIT; + dns_rdata_t cds_sha256 = DNS_RDATA_INIT; dns_rdata_t cdnskeyrdata = DNS_RDATA_INIT; dns_name_t *origin = dst_key_name(key->key); @@ -1918,69 +1918,83 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, &cdnskeyrdata)); /* + * We construct the SHA-1 version of the record so we can + * delete any old records generated by previous versions of + * BIND. We only add SHA-256 records. + * * XXXMPA we need to be able to specify the DS algorithms * to be used here and below with rmkeys. */ RETERR(dns_ds_buildrdata(origin, &cdnskeyrdata, DNS_DSDIGEST_SHA1, dsbuf1, - &cdsrdata1)); + &cds_sha1)); RETERR(dns_ds_buildrdata(origin, &cdnskeyrdata, DNS_DSDIGEST_SHA256, dsbuf2, - &cdsrdata2)); + &cds_sha256)); /* * Now that the we have created the DS records convert * the rdata to CDNSKEY and CDS for comparison. */ cdnskeyrdata.type = dns_rdatatype_cdnskey; - cdsrdata1.type = dns_rdatatype_cds; - cdsrdata2.type = dns_rdatatype_cds; + cds_sha1.type = dns_rdatatype_cds; + cds_sha256.type = dns_rdatatype_cds; if (syncpublish(key->key, now)) { if (!dns_rdataset_isassociated(cdnskey) || !exists(cdnskey, &cdnskeyrdata)) + { RETERR(publish(&cdnskeyrdata, diff, origin, ttl, mctx)); + } + /* Only publish SHA-256 (SHA-1 is deprecated) */ if (!dns_rdataset_isassociated(cds) || - !exists(cds, &cdsrdata1)) - RETERR(publish(&cdsrdata1, diff, origin, - ttl, mctx)); - if (!dns_rdataset_isassociated(cds) || - !exists(cds, &cdsrdata2)) - RETERR(publish(&cdsrdata2, diff, origin, + !exists(cds, &cds_sha256)) + { + RETERR(publish(&cds_sha256, diff, origin, ttl, mctx)); + } } if (dns_rdataset_isassociated(cds) && - syncdelete(key->key, now)) { - if (exists(cds, &cdsrdata1)) - RETERR(delrdata(&cdsrdata1, diff, origin, + syncdelete(key->key, now)) + { + /* Delete both SHA-1 and SHA-256 */ + if (exists(cds, &cds_sha1)) { + RETERR(delrdata(&cds_sha1, diff, origin, cds->ttl, mctx)); - if (exists(cds, &cdsrdata2)) - RETERR(delrdata(&cdsrdata2, diff, origin, + } + if (exists(cds, &cds_sha256)) { + RETERR(delrdata(&cds_sha256, diff, origin, cds->ttl, mctx)); + } } if (dns_rdataset_isassociated(cdnskey) && - syncdelete(key->key, now)) { - if (exists(cdnskey, &cdnskeyrdata)) + syncdelete(key->key, now)) + { + if (exists(cdnskey, &cdnskeyrdata)) { RETERR(delrdata(&cdnskeyrdata, diff, origin, cdnskey->ttl, mctx)); + } } } if (!dns_rdataset_isassociated(cds) && !dns_rdataset_isassociated(cdnskey)) + { return (ISC_R_SUCCESS); + } /* * Unconditionaly remove CDS/DNSKEY records for removed keys. */ for (key = ISC_LIST_HEAD(*rmkeys); key != NULL; - key = ISC_LIST_NEXT(key, link)) { - dns_rdata_t cdsrdata1 = DNS_RDATA_INIT; - dns_rdata_t cdsrdata2 = DNS_RDATA_INIT; + key = ISC_LIST_NEXT(key, link)) + { + dns_rdata_t cds_sha1 = DNS_RDATA_INIT; + dns_rdata_t cds_sha256 = DNS_RDATA_INIT; dns_rdata_t cdnskeyrdata = DNS_RDATA_INIT; dns_name_t *origin = dst_key_name(key->key); @@ -1990,22 +2004,25 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, if (dns_rdataset_isassociated(cds)) { RETERR(dns_ds_buildrdata(origin, &cdnskeyrdata, DNS_DSDIGEST_SHA1, dsbuf1, - &cdsrdata1)); + &cds_sha1)); RETERR(dns_ds_buildrdata(origin, &cdnskeyrdata, DNS_DSDIGEST_SHA256, dsbuf2, - &cdsrdata2)); - if (exists(cds, &cdsrdata1)) - RETERR(delrdata(&cdsrdata1, diff, origin, + &cds_sha256)); + if (exists(cds, &cds_sha1)) { + RETERR(delrdata(&cds_sha1, diff, origin, cds->ttl, mctx)); - if (exists(cds, &cdsrdata2)) - RETERR(delrdata(&cdsrdata2, diff, origin, + } + if (exists(cds, &cds_sha256)) { + RETERR(delrdata(&cds_sha256, diff, origin, cds->ttl, mctx)); + } } if (dns_rdataset_isassociated(cdnskey)) { - if (exists(cdnskey, &cdnskeyrdata)) + if (exists(cdnskey, &cdnskeyrdata)) { RETERR(delrdata(&cdnskeyrdata, diff, origin, cdnskey->ttl, mctx)); + } } } From 793d358cd62d9336f01403e6c2b170dd27301efb Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Wed, 30 Jan 2019 22:10:12 +0000 Subject: [PATCH 7/7] add CHANGES and release note --- CHANGES | 3 +++ doc/arm/notes.xml | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CHANGES b/CHANGES index f8b2ab0343..587bd10c72 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +5230. [protocol] The SHA-1 hash algorithm is no longer used when + generating DS and CDS records. [GL #1015] + 5229. [protocol] Enforce known SSHFP fingerprint lengths. [GL #852] 5228. [func] If trusted-keys and managed-keys were configured diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 2781c728a8..732da2f8da 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -144,6 +144,21 @@ configuration error. [GL #868] + + + DS and CDS records are now generated with SHA-256 digests + only, instead of both SHA-1 and SHA-256. This affects the + default output of dnssec-dsfromkey, the + dsset files generated by + dnssec-signzone, the DS records added to + a zone by dnssec-signzone based on + keyset files, the CDS records added to + a zone by named and + dnssec-signzone based on "sync" timing + parameters in key files, and the checks performed by + dnssec-checkds. + +