]> 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:30:37 +0000 (01:30 +0000)
committerMark Andrews <marka@isc.org>
Mon, 26 Feb 2007 01:30:37 +0000 (01:30 +0000)
                        [RT #16622]

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

diff --git a/CHANGES b/CHANGES
index e0dc985c09bd0ea1deade3aee1e949d53ae57c07..d2e97854a0b34bc59355dadcd16c0e4d298b6a1c 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 b28435c8bd54607e65d5c0c9149531d67f33863c..dc79f84c0f4ed28cf0022c4947bcdfdbf3645341 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dlv_32769.c,v 1.2.4.2 2006/02/19 06:50:46 marka Exp $ */
+/* $Id: dlv_32769.c,v 1.2.4.3 2007/02/26 01:30:37 marka Exp $ */
 
 /* draft-ietf-dnsext-delegation-signer-05.txt */
 
 
 #define RRTYPE_DLV_ATTRIBUTES 0
 
+#include <isc/sha1.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 +68,15 @@ 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
+               length = -1;
        return (isc_hex_tobuffer(lexer, target, -1));
 }
 
@@ -130,9 +141,23 @@ 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))
                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;
        isc_buffer_forward(source, sr.length);
        return (mem_tobuffer(target, sr.base, sr.length));
 }
@@ -174,6 +199,11 @@ 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;
+       }
 
        UNUSED(type);
        UNUSED(rdclass);
index 0206b6f06c226763d031fb459f53c231c530e0e6..58a81c37ecf8543c14d598428ebf84b8a82a2648 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: ds_43.c,v 1.6.2.4 2005/09/06 07:29:31 marka Exp $ */
+/* $Id: ds_43.c,v 1.6.2.5 2007/02/26 01:30:37 marka Exp $ */
 
 /* draft-ietf-dnsext-delegation-signer-05.txt */
 
 #define RRTYPE_DS_ATTRIBUTES \
        (DNS_RDATATYPEATTR_DNSSEC|DNS_RDATATYPEATTR_ATPARENT)
 
+#include <isc/sha1.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 +68,16 @@ 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
+               length = -1;
+       return (isc_hex_tobuffer(lexer, target, length));
 }
 
 static inline isc_result_t
@@ -132,9 +141,23 @@ 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))
                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;
+
        isc_buffer_forward(source, sr.length);
        return (mem_tobuffer(target, sr.base, sr.length));
 }
@@ -176,6 +199,11 @@ 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;
+       }
 
        UNUSED(type);
        UNUSED(rdclass);