]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2145. [bug] Check DS/DLV digest lengths for known digests.
authorMark Andrews <marka@isc.org>
Mon, 26 Feb 2007 01:20:44 +0000 (01:20 +0000)
committerMark Andrews <marka@isc.org>
Mon, 26 Feb 2007 01:20:44 +0000 (01:20 +0000)
                        [RT #16622]

CHANGES
lib/dns/rdata/generic/dlv_32769.c
lib/dns/rdata/generic/ds_43.c
lib/dns/validator.c

diff --git a/CHANGES b/CHANGES
index adda5fcfe3a08229ef2514f6c53589b12ca8e6b6..3df60d23e0427490c9defdf6c21bd72062d92f60 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2145.  [bug]           Check DS/DLV digest lengths for known digests.
+                       [RT #16622]
+
 2144.  [cleanup]       Suppress logging of SERVFAIL from forwarders.
                        [RT #16619]
 
index 0be365a80f0799dc66c662891379fd9283413d58..7a534ff5282f12be31c46c2b7e16d5e404c089cb 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dlv_32769.c,v 1.3 2006/02/19 06:50:48 marka Exp $ */
+/* $Id: dlv_32769.c,v 1.4 2007/02/26 01:20:44 marka Exp $ */
 
 /* draft-ietf-dnsext-delegation-signer-05.txt */
 
 
 #define RRTYPE_DLV_ATTRIBUTES 0
 
+#include <isc/sha1.h>
+#include <isc/sha2.h>
+
+#include <dns/ds.h>
+
+
 static inline isc_result_t
 fromtext_dlv(ARGS_FROMTEXT) {
        isc_token_t token;
+       unsigned char c;
+       int length;
 
        REQUIRE(type == 32769);
 
@@ -61,11 +69,17 @@ fromtext_dlv(ARGS_FROMTEXT) {
        if (token.value.as_ulong > 0xffU)
                RETTOK(ISC_R_RANGE);
        RETERR(uint8_tobuffer(token.value.as_ulong, target));
-       type = (isc_uint16_t) token.value.as_ulong;
+       c = (unsigned char) token.value.as_ulong;
 
        /*
         * Digest.
         */
+       if (c == DNS_DSDIGEST_SHA1)
+               length = ISC_SHA1_DIGESTLENGTH;
+       else if (c == DNS_DSDIGEST_SHA256)
+               length = ISC_SHA256_DIGESTLENGTH;
+       else
+               length = -1;
        return (isc_hex_tobuffer(lexer, target, -1));
 }
 
@@ -130,9 +144,27 @@ fromwire_dlv(ARGS_FROMWIRE) {
        UNUSED(options);
 
        isc_buffer_activeregion(source, &sr);
-       if (sr.length < 4)
+       /*
+        * Check digest lengths if we know them.
+        */
+       if (sr.length < 4 ||
+           (sr.base[3] == DNS_DSDIGEST_SHA1 &&
+            sr.length < 4 + ISC_SHA1_DIGESTLENGTH) ||
+           (sr.base[3] == DNS_DSDIGEST_SHA256 &&
+            sr.length < 4 + ISC_SHA256_DIGESTLENGTH))
                return (ISC_R_UNEXPECTEDEND);
 
+       /*
+        * Only copy digest lengths if we know them.
+        * If there is extra data dns_rdata_fromwire() will
+        * detect that.
+        */
+       if (sr.base[3] == DNS_DSDIGEST_SHA1)
+               sr.length = 4 + ISC_SHA1_DIGESTLENGTH;
+       else if (sr.base[3] == DNS_DSDIGEST_SHA256)
+               sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
        isc_buffer_forward(source, sr.length);
        return (mem_tobuffer(target, sr.base, sr.length));
 }
@@ -174,6 +206,14 @@ fromstruct_dlv(ARGS_FROMSTRUCT) {
        REQUIRE(source != NULL);
        REQUIRE(dlv->common.rdtype == type);
        REQUIRE(dlv->common.rdclass == rdclass);
+       switch (dlv->digest_type) {
+       case DNS_DSDIGEST_SHA1:
+               REQUIRE(dlv->length == ISC_SHA1_DIGESTLENGTH);
+               break;
+       case DNS_DSDIGEST_SHA256:
+               REQUIRE(dlv->length == ISC_SHA256_DIGESTLENGTH);
+               break;
+       }
 
        UNUSED(type);
        UNUSED(rdclass);
index df8e3bafbc2f00c2ca3b806a3a97cbf4648d0789..b9bb763c754ae6300962fbab17521db74d04d7ce 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: ds_43.c,v 1.9 2005/09/06 07:29:31 marka Exp $ */
+/* $Id: ds_43.c,v 1.10 2007/02/26 01:20:44 marka Exp $ */
 
 /* draft-ietf-dnsext-delegation-signer-05.txt */
 
 #define RRTYPE_DS_ATTRIBUTES \
        (DNS_RDATATYPEATTR_DNSSEC|DNS_RDATATYPEATTR_ATPARENT)
 
+#include <isc/sha1.h>
+#include <isc/sha2.h>
+
+#include <dns/ds.h>
+
 static inline isc_result_t
 fromtext_ds(ARGS_FROMTEXT) {
        isc_token_t token;
        unsigned char c;
+       int length;
 
        REQUIRE(type == 43);
 
@@ -63,12 +69,18 @@ fromtext_ds(ARGS_FROMTEXT) {
        if (token.value.as_ulong > 0xffU)
                RETTOK(ISC_R_RANGE);
        RETERR(uint8_tobuffer(token.value.as_ulong, target));
-       type = (isc_uint16_t) token.value.as_ulong;
+       c = (unsigned char) token.value.as_ulong;
 
        /*
         * Digest.
         */
-       return (isc_hex_tobuffer(lexer, target, -1));
+       if (c == DNS_DSDIGEST_SHA1)
+               length = ISC_SHA1_DIGESTLENGTH;
+       else if (c == DNS_DSDIGEST_SHA256)
+               length = ISC_SHA256_DIGESTLENGTH;
+       else
+               length = -1;
+       return (isc_hex_tobuffer(lexer, target, length));
 }
 
 static inline isc_result_t
@@ -132,9 +144,27 @@ fromwire_ds(ARGS_FROMWIRE) {
        UNUSED(options);
 
        isc_buffer_activeregion(source, &sr);
-       if (sr.length < 4)
+
+       /*
+        * Check digest lengths if we know them.
+        */
+       if (sr.length < 4 ||
+           (sr.base[3] == DNS_DSDIGEST_SHA1 &&
+            sr.length < 4 + ISC_SHA1_DIGESTLENGTH) ||
+           (sr.base[3] == DNS_DSDIGEST_SHA256 &&
+            sr.length < 4 + ISC_SHA256_DIGESTLENGTH))
                return (ISC_R_UNEXPECTEDEND);
 
+       /*
+        * Only copy digest lengths if we know them.
+        * If there is extra data dns_rdata_fromwire() will
+        * detect that.
+        */
+       if (sr.base[3] == DNS_DSDIGEST_SHA1)
+               sr.length = 4 + ISC_SHA1_DIGESTLENGTH;
+       else if (sr.base[3] == DNS_DSDIGEST_SHA256)
+               sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
+
        isc_buffer_forward(source, sr.length);
        return (mem_tobuffer(target, sr.base, sr.length));
 }
@@ -176,6 +206,14 @@ fromstruct_ds(ARGS_FROMSTRUCT) {
        REQUIRE(source != NULL);
        REQUIRE(ds->common.rdtype == type);
        REQUIRE(ds->common.rdclass == rdclass);
+       switch (ds->digest_type) {
+       case DNS_DSDIGEST_SHA1:
+               REQUIRE(ds->length == ISC_SHA1_DIGESTLENGTH);
+               break;
+       case DNS_DSDIGEST_SHA256:
+               REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH);
+               break;
+       }
 
        UNUSED(type);
        UNUSED(rdclass);
index e3c2f2b59a70f0dbdd0b9bd2b019c5ab147b1f8a..ac2a6f0b94cec2b31523ce21ae5f2354a4cebd8e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: validator.c,v 1.149 2007/01/08 02:45:04 marka Exp $ */
+/* $Id: validator.c,v 1.150 2007/02/26 01:20:43 marka Exp $ */
 
 #include <config.h>
 
@@ -24,6 +24,7 @@
 #include <isc/string.h>
 #include <isc/task.h>
 #include <isc/util.h>
+#include <isc/sha2.h>
 
 #include <dns/db.h>
 #include <dns/ds.h>
@@ -1502,7 +1503,8 @@ dlv_validatezonekey(dns_validator_t *val) {
                                                      dlv.algorithm))
                        continue;
 
-               if (dlv.digest_type == DNS_DSDIGEST_SHA256) {
+               if (dlv.digest_type == DNS_DSDIGEST_SHA256 &&
+                   dlv.length == ISC_SHA256_DIGESTLENGTH) {
                        digest_type = DNS_DSDIGEST_SHA256;
                        break;
                }
@@ -1835,7 +1837,8 @@ validatezonekey(dns_validator_t *val) {
                                                      ds.algorithm))
                        continue;
 
-               if (ds.digest_type == DNS_DSDIGEST_SHA256) {
+               if (ds.digest_type == DNS_DSDIGEST_SHA256 &&
+                   ds.length == ISC_SHA256_DIGESTLENGTH) {
                        digest_type = DNS_DSDIGEST_SHA256;
                        break;
                }