]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Deprecate SHA-1 in `dnssec-dsfromkey`
authorTony Finch <dot@dotat.at>
Thu, 31 Jan 2019 17:05:57 +0000 (17:05 +0000)
committerEvan Hunt <each@isc.org>
Thu, 9 May 2019 01:17:55 +0000 (18:17 -0700)
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
bin/dnssec/dnssec-dsfromkey.c
bin/dnssec/dnssec-dsfromkey.docbook
bin/dnssec/dnssectool.c
bin/dnssec/dnssectool.h
bin/python/isc/checkds.py.in
bin/tests/system/cds/setup.sh
bin/tests/system/dnssec/tests.sh

index 198ebcf959a23480458054e548c2aa0ee753ea82..ba54acbd8a1831dffb0779347b90a65d7a15baf4 100644 (file)
@@ -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);
index 1fdded5ebb5a97ca4fc2d5338f3885fb3600292a..5ea294b93e9338bd6051520211ab03202979dd66 100644 (file)
@@ -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);
+       }
 }
index 7f0039ebb1dfbd3e60cf937e65dd1d2d48da8e7f..d67e4041782ea9ed16ee12e22b8dac7cacad70a7 100644 (file)
@@ -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>
        <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>
        <term>-2</term>
        <listitem>
          <para>
-           An abbreviation for <option>-a SHA-256</option>
+           An abbreviation for <option>-a SHA-256</option>.
          </para>
        </listitem>
       </varlistentry>
            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>
index 5cfd8e74d6b4bc428499abcca8b5b2b4dfd3f436..e1205d05f88ad8c7d52c701e11bf5ad386211d5e 100644 (file)
@@ -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;
index 16533669a63a51626790e525d5e27ed80f102d97..e4798e8336b9916430fa06c182987891bafb0d22 100644 (file)
@@ -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);
index b5cbe3fd05f31e8eeb9afbcfda211fa925e9c4b1..1f1963f3aef543738313c0f45671bb37ce94117f 100644 (file)
@@ -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)
index ca13261af58781344e496a1f84e75b22e4a10555..92bd9c94d46d0e4ce2768fd72c0830755f971499 100644 (file)
@@ -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
index 4cf69f0beb5c93fbb1b6e11d45f69536e1f15d63..5dc48d7cf875f9bc9c37a725c191a502b42ae264 100644 (file)
@@ -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