]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
rndc dnssec -checkds set algorithm
authorMatthijs Mekking <matthijs@isc.org>
Tue, 4 Aug 2020 08:33:19 +0000 (10:33 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Fri, 7 Aug 2020 09:26:09 +0000 (11:26 +0200)
In the rare case that you have multiple keys acting as KSK and that
have the same keytag, you can now set the algorithm when calling
'-checkds'.

bin/named/server.c
bin/rndc/rndc.c
bin/rndc/rndc.rst
bin/tests/system/kasp/tests.sh
doc/man/rndc.8in
lib/dns/include/dns/keymgr.h
lib/dns/keymgr.c

index 89f8eaa29b9c9c3de819ab50f371459ff91d1ba5..547df1147abb155cfad8706a59071982965b56ac 100644 (file)
@@ -14528,6 +14528,7 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex,
        /* variables for -checkds */
        bool checkds = false, dspublish = false, use_keyid = false;
        dns_keytag_t keyid = 0;
+       uint8_t algorithm = 0;
        /* variables for -status */
        bool status = false;
        char output[4096];
@@ -14565,8 +14566,23 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex,
                        if (ptr == NULL) {
                                msg = "Bad format";
                                CHECK(ISC_R_UNEXPECTEDEND);
-                       }
-                       if (argcheck(ptr, "key")) {
+                       } else if (argcheck(ptr, "alg")) {
+                               isc_consttextregion_t alg;
+                               ptr = next_token(lex, text);
+                               if (ptr == NULL) {
+                                       msg = "No key algorithm specified";
+                                       CHECK(ISC_R_UNEXPECTEDEND);
+                               }
+                               alg.base = ptr;
+                               alg.length = strlen(alg.base);
+                               result = dns_secalg_fromtext(
+                                       &algorithm, (isc_textregion_t *)&alg);
+                               if (result != ISC_R_SUCCESS) {
+                                       msg = "Bad algorithm";
+                                       CHECK(DNS_R_SYNTAX);
+                               }
+                               continue;
+                       } else if (argcheck(ptr, "key")) {
                                uint16_t id;
                                ptr = next_token(lex, text);
                                if (ptr == NULL) {
@@ -14595,14 +14611,19 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex,
                                 * No arguments provided, so we must be
                                 * parsing "published|withdrawn".
                                 */
-                               if (strcasecmp(ptr, "publish") == 0) {
+                               if (strcasecmp(ptr, "published") == 0) {
                                        dspublish = true;
-                               } else if (strcasecmp(ptr, "withdraw") != 0) {
+                               } else if (strcasecmp(ptr, "withdrawn") != 0) {
                                        CHECK(DNS_R_SYNTAX);
                                }
                        }
                        break;
                }
+
+               if (algorithm > 0 && !use_keyid) {
+                       msg = "Key id is required when setting algorithm";
+                       CHECK(DNS_R_SYNTAX);
+               }
        } else {
                CHECK(DNS_R_SYNTAX);
        }
@@ -14658,7 +14679,8 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex,
                LOCK(&kasp->lock);
                if (use_keyid) {
                        result = dns_keymgr_checkds_id(kasp, &keys, dir, when,
-                                                      dspublish, keyid);
+                                                      dspublish, keyid,
+                                                      (unsigned int)algorithm);
                } else {
                        result = dns_keymgr_checkds(kasp, &keys, dir, when,
                                                    dspublish);
index e68c2e2244f5e2a61989f769bd9401d9250624d1..53a1cdccd6e6bd342170ec069efa293b30e60685 100644 (file)
@@ -108,10 +108,11 @@ command is one of the following:\n\
                Add zone to given view. Requires allow-new-zones option.\n\
   delzone [-clean] zone [class [view]]\n\
                Removes zone from given view.\n\
-  dnssec -checkds [-key id] [-when time] (published|withdrawn) zone [class [view]]\n\
+  dnssec -checkds [-key id [-alg algorithm] [-when time] (published|withdrawn) zone [class [view]]\n\
                Mark the DS record for the KSK of the given zone as seen\n\
                in the parent.  If the zone has multiple KSKs, select a\n\
-               specific key by providing the keytag with -key id.\n\
+               specific key by providing the keytag with -key id and\n\
+               optionally the key's algorithm with -alg algorithm.\n\
                Requires the zone to have a dnssec-policy.\n\
   dnssec -status zone [class [view]]\n\
                Show the DNSSEC signing state for the specified zone.\n\
index 72e42384cb1df479a109aaa3bfd0be185dc0ac71..f6501d402267230ea31ab4a4c94aee653303baf7 100644 (file)
@@ -161,7 +161,7 @@ Currently supported commands are:
 
    See also ``rndc addzone`` and ``rndc modzone``.
 
-``dnssec`` ( **-status** | **-checkds** [**-key** *id*] [**-when** *time*] ( *published* | *withdrawn* )) *zone* [*class* [*view*]]
+``dnssec`` ( **-status** | **-checkds** [**-key** *id* [**-alg** *algorithm*]] [**-when** *time*] ( *published* | *withdrawn* )) *zone* [*class* [*view*]]
    This command allows you to interact with the "dnssec-policy" of a given
    zone.
 
@@ -172,9 +172,10 @@ Currently supported commands are:
    key has been seen published into or withdrawn from the parent.  This is
    required in order to complete a KSK rollover.  If the ``-key id`` argument
    is specified, look for the key with the given identifier, otherwise if there
-   is only one key acting as a KSK in the zone, assume the DS of that key.
-   The time that the DS has been published or withdrawn is set to now, unless
-   otherwise specified with the argument ``-when time``.
+   is only one key acting as a KSK in the zone, assume the DS of that key (if
+   there are multiple keys with the same tag, use ``-alg algorithm`` to
+   select the correct algorithm).  The time that the DS has been published or
+   withdrawn is set to now, unless otherwise specified with the argument ``-when time``.
 
 ``dnstap`` ( **-reopen** | **-roll** [*number*] )
    This command closes and re-opens DNSTAP output files. ``rndc dnstap -reopen`` allows
index d83017b6bab203305abb7ecafdd4304013b1e9d2..335b411f1f986064d9786b9f1759d76026669dec 100644 (file)
@@ -1476,6 +1476,22 @@ grep "DSRemoved:" "${basefile2}.state" > /dev/null && log_error "DSPublish incor
 test "$ret" -eq 0 || echo_i "failed"
 status=$((status+ret))
 
+n=$((n+1))
+echo_i "checkds published does not set DSPublish for zone $ZONE (wrong algorithm) ($n)"
+rndccmd "$SERVER" dnssec -checkds -key $(key_get KEY1 ID) -alg 8 "published" "$ZONE" > rndc.dnssec.checkds.out.$ZONE.$n
+grep "DSPublish:" "${basefile1}.state" > /dev/null && log_error "DSPublish incorrectly set in ${basefile1}"
+grep "DSPublish:" "${basefile2}.state" > /dev/null && log_error "DSPublish incorrectly set in ${basefile2}"
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checkds withdrawn does not set DSRemoved for zone $ZONE (wrong algorithm) ($n)"
+rndccmd "$SERVER" dnssec -checkds -key $(key_get KEY1 ID) -alg RSASHA256 "withdrawn" "$ZONE" > rndc.dnssec.checkds.out.$ZONE.$n
+grep "DSRemoved:" "${basefile1}.state" > /dev/null && log_error "DSRemoved incorrectly set in ${basefile1}"
+grep "DSRemoved:" "${basefile2}.state" > /dev/null && log_error "DSRemoved incorrectly set in ${basefile2}"
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
 n=$((n+1))
 echo_i "checkds published -key correctly sets DSPublish for key $(key_get KEY1 ID) zone $ZONE (multiple KSK) ($n)"
 rndc_checkds "$SERVER" "$DIR" $(key_get KEY1 ID) "20190102121314" "published" "$ZONE"
index 81fd8f642b44ea1f026909747539531bdd74f8b5..59f03abe6861d0b3e042e49790c490c2d9a9fbbd 100644 (file)
@@ -161,7 +161,7 @@ recreated. To remove it permanently, it must also be removed from
 .sp
 See also \fBrndc addzone\fP and \fBrndc modzone\fP\&.
 .TP
-\fBdnssec\fP ( \fB\-status\fP | \fB\-checkds\fP [\fB\-key\fP \fIid\fP] [\fB\-when\fP \fItime\fP] ( \fIpublished\fP | \fIwithdrawn\fP )) \fIzone\fP [\fIclass\fP [\fIview\fP]]
+\fBdnssec\fP ( \fB\-status\fP | \fB\-checkds\fP [\fB\-key\fP \fIid\fP [\fB\-alg\fP \fIalgorithm\fP]] [\fB\-when\fP \fItime\fP] ( \fIpublished\fP | \fIwithdrawn\fP )) \fIzone\fP [\fIclass\fP [\fIview\fP]]
 This command allows you to interact with the "dnssec\-policy" of a given
 zone.
 .sp
@@ -172,9 +172,10 @@ zone.
 key has been seen published into or withdrawn from the parent.  This is
 required in order to complete a KSK rollover.  If the \fB\-key id\fP argument
 is specified, look for the key with the given identifier, otherwise if there
-is only one key acting as a KSK in the zone, assume the DS of that key.
-The time that the DS has been published or withdrawn is set to now, unless
-otherwise specified with the argument \fB\-when time\fP\&.
+is only one key acting as a KSK in the zone, assume the DS of that key (if
+there are multiple keys with the same tag, use \fB\-alg algorithm\fP to
+select the correct algorithm).  The time that the DS has been published or
+withdrawn is set to now, unless otherwise specified with the argument \fB\-when time\fP\&.
 .TP
 \fBdnstap\fP ( \fB\-reopen\fP | \fB\-roll\fP [\fInumber\fP] )
 This command closes and re\-opens DNSTAP output files. \fBrndc dnstap \-reopen\fP allows
index 3e8ad6af307bfa5fcab502230887edb27ba38c04..cdbc791efe992b0b94e1f8718517a73de486fa4f 100644 (file)
@@ -57,12 +57,13 @@ dns_keymgr_checkds(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
 isc_result_t
 dns_keymgr_checkds_id(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
                      const char *directory, isc_stdtime_t now, bool dspublish,
-                     dns_keytag_t id);
+                     dns_keytag_t id, unsigned int algorithm);
 /*%<
  * Check DS for one key in 'keyring'. The key must have the KSK role.
  * If 'dspublish' is set to true, set the DS Publish time to 'now'.
  * If 'dspublish' is set to false, set the DS Removed time to 'now'.
  * If a specific key 'id' is given it must match the keytag.
+ * If the 'algorithm' is non-zero, it must match the key's algorithm.
  * The result is stored in the key state file.
  *
  *     Requires:
index c8a5badb7835b74d271096b5d8c20159a5e525f0..1a24786c3956d40835ac043a9bf9fa8d70b154b2 100644 (file)
@@ -1873,7 +1873,7 @@ failure:
 static isc_result_t
 keymgr_checkds(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
               const char *directory, isc_stdtime_t now, bool dspublish,
-              dns_keytag_t id, bool check_id) {
+              dns_keytag_t id, unsigned int alg, bool check_id) {
        int options = (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC | DST_TYPE_STATE);
        isc_dir_t dir;
        isc_result_t result;
@@ -1893,6 +1893,9 @@ keymgr_checkds(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
                        if (check_id && dst_key_id(dkey->key) != id) {
                                continue;
                        }
+                       if (alg > 0 && dst_key_alg(dkey->key) != alg) {
+                               continue;
+                       }
 
                        if (ksk_key != NULL) {
                                /*
@@ -1935,16 +1938,16 @@ keymgr_checkds(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
 isc_result_t
 dns_keymgr_checkds(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
                   const char *directory, isc_stdtime_t now, bool dspublish) {
-       return (keymgr_checkds(kasp, keyring, directory, now, dspublish, 0,
+       return (keymgr_checkds(kasp, keyring, directory, now, dspublish, 0, 0,
                               false));
 }
 
 isc_result_t
 dns_keymgr_checkds_id(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
                      const char *directory, isc_stdtime_t now, bool dspublish,
-                     dns_keytag_t id) {
+                     dns_keytag_t id, unsigned int alg) {
        return (keymgr_checkds(kasp, keyring, directory, now, dspublish, id,
-                              true));
+                              alg, true));
 }
 
 static void