]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2495. [bug] Tighten RRSIG checks. [RT #18795]
authorMark Andrews <marka@isc.org>
Thu, 20 Nov 2008 02:02:44 +0000 (02:02 +0000)
committerMark Andrews <marka@isc.org>
Thu, 20 Nov 2008 02:02:44 +0000 (02:02 +0000)
CHANGES
bin/dnssec/dnssec-signzone.c
lib/dns/dnssec.c
lib/dns/dst_api.c
lib/dns/validator.c

diff --git a/CHANGES b/CHANGES
index 36f41b05de3330389e8f76e4443ac55d28a74063..a976c458ee5387bec1e19a258d839299fd333702 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,8 @@
                        warning or crash named with the debug 1 level
                        of logging. [RT #18917]
 
+2495.  [bug]           Tighten RRSIG checks. [RT #18795]
+
 2494.  [bug]           dns/sdlz.h and dns/dlz.h were not being installed.
                        [RT #18826]
 
index 9b491691044089c017406601a7407b588ee1205f..3b49492730ad76a9b450a6cbc5d43de517c99e34 100644 (file)
@@ -16,7 +16,7 @@
  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dnssec-signzone.c,v 1.177.18.26 2008/06/02 23:46:01 tbox Exp $ */
+/* $Id: dnssec-signzone.c,v 1.177.18.27 2008/11/20 02:02:44 marka Exp $ */
 
 /*! \file */
 
@@ -2106,6 +2106,9 @@ main(int argc, char *argv[]) {
                                fatal("cannot load dnskey %s: %s", argv[i],
                                      isc_result_totext(result));
 
+                       if (!dns_name_equal(gorigin, dst_key_name(newkey)))
+                               fatal("key %s not at origin\n", argv[i]);
+
                        key = ISC_LIST_HEAD(keylist);
                        while (key != NULL) {
                                dst_key_t *dkey = key->key;
@@ -2143,6 +2146,9 @@ main(int argc, char *argv[]) {
                        fatal("cannot load dnskey %s: %s", dskeyfile[i],
                              isc_result_totext(result));
 
+               if (!dns_name_equal(gorigin, dst_key_name(newkey)))
+                       fatal("key %s not at origin\n", dskeyfile[i]);
+
                key = ISC_LIST_HEAD(keylist);
                while (key != NULL) {
                        dst_key_t *dkey = key->key;
index 75ca44045359677dab07ae4414654597a6bdd09f..7d425d5111846eb046c6beada82f7da0e92b7ea7 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 /*
- * $Id: dnssec.c,v 1.81.18.10 2007/09/14 04:35:42 marka Exp $
+ * $Id: dnssec.c,v 1.81.18.11 2008/11/20 02:02:44 marka Exp $
  */
 
 /*! \file */
@@ -366,6 +366,9 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
        if (ret != ISC_R_SUCCESS)
                return (ret);
 
+       if (set->type != sig.covered)
+               return (DNS_R_SIGINVALID);
+
        if (isc_serial_lt(sig.timeexpire, sig.timesigned))
                return (DNS_R_SIGINVALID);
 
@@ -381,6 +384,27 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
                        return (DNS_R_SIGEXPIRED);
        }
 
+       /*
+        * NS, SOA and DNSSKEY records are signed by their owner.
+        * DS records are signed by the parent.
+        */
+       switch (set->type) {
+       case dns_rdatatype_ns:
+       case dns_rdatatype_soa:
+       case dns_rdatatype_dnskey:
+               if (!dns_name_equal(name, &sig.signer))
+                       return (DNS_R_SIGINVALID);
+               break;
+       case dns_rdatatype_ds:
+               if (dns_name_equal(name, &sig.signer))
+                       return (DNS_R_SIGINVALID);
+               /* FALLTHROUGH */
+       default:
+               if (!dns_name_issubdomain(name, &sig.signer))
+                       return (DNS_R_SIGINVALID);
+               break;
+       }
+
        /*
         * Is the key allowed to sign data?
         */
@@ -541,6 +565,9 @@ dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver,
                if (!is_zone_key(pubkey) ||
                    (dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0)
                        goto next;
+               /* Corrupted .key file? */
+               if (!dns_name_equal(name, dst_key_name(pubkey)))
+                       goto next;
                keys[count] = NULL;
                result = dst_key_fromfile(dst_key_name(pubkey),
                                          dst_key_id(pubkey),
index 7d98e10a7f3a6a43110536c109f2f6c934111f90..5038204ae9c6969fbf334c36d8e1703c73a0f826 100644 (file)
@@ -18,7 +18,7 @@
 
 /*
  * Principal Author: Brian Wellington
- * $Id: dst_api.c,v 1.1.6.7 2006/01/27 23:57:44 marka Exp $
+ * $Id: dst_api.c,v 1.1.6.8 2008/11/20 02:02:44 marka Exp $
  */
 
 /*! \file */
@@ -925,6 +925,13 @@ dst_key_read_public(const char *filename, int type,
        NEXTTOKEN(lex, opt, &token);
        if (token.type != isc_tokentype_string)
                BADTOKEN();
+
+       /*
+        * We don't support "@" in .key files.
+        */
+       if (!strcmp(DST_AS_STR(token), "@"))
+               BADTOKEN();
+
        dns_fixedname_init(&name);
        isc_buffer_init(&b, DST_AS_STR(token), strlen(DST_AS_STR(token)));
        isc_buffer_add(&b, strlen(DST_AS_STR(token)));
index e68633646ac5cb1291f5e58eca6d7ad72ec2bd22..c60c4ae390761d3cb625ae5d3a7010f6a735c42e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: validator.c,v 1.119.18.41 2008/08/21 04:59:42 marka Exp $ */
+/* $Id: validator.c,v 1.119.18.42 2008/11/20 02:02:44 marka Exp $ */
 
 /*! \file */
 
@@ -1132,6 +1132,23 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
                 */
                if (dns_rdatatype_atparent(val->event->rdataset->type))
                        return (DNS_R_CONTINUE);
+       } else {
+               /*
+                * SOA and NS RRsets can only be signed by a key with   
+                * the same name.
+                */
+               if (val->event->rdataset->type == dns_rdatatype_soa ||
+                   val->event->rdataset->type == dns_rdatatype_ns) {
+                       const char *typename;
+
+                       if (val->event->rdataset->type == dns_rdatatype_soa)
+                               typename = "SOA";
+                       else
+                               typename = "NS";
+                       validator_log(val, ISC_LOG_DEBUG(3),
+                                     "%s signer mismatch", typename);
+                       return (DNS_R_CONTINUE);
+               }
        }
 
        /*
@@ -1703,6 +1720,10 @@ validatezonekey(dns_validator_t *val) {
                                             &sigrdata);
                        result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
                        RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+                       if (!dns_name_equal(val->event->name, &sig.signer))
+                               continue;
+
                        result = dns_keytable_findkeynode(val->keytable,
                                                          val->event->name,
                                                          sig.algorithm,
@@ -1943,7 +1964,11 @@ validatezonekey(dns_validator_t *val) {
                        if (ds.key_tag != sig.keyid ||
                            ds.algorithm != sig.algorithm)
                                continue;
-
+                       if (!dns_name_equal(val->event->name, &sig.signer)) {
+                               validator_log(val, ISC_LOG_DEBUG(3),
+                                             "DNSKEY signer mismatch");
+                               continue;
+                       }
                        dstkey = NULL;
                        result = dns_dnssec_keyfromrdata(val->event->name,
                                                         &keyrdata,