Browse Source

[trac117] made NSEC "from wire" tests more complete.

JINMEI Tatuya 14 years ago
parent
commit
42cd95d56e

+ 8 - 12
src/lib/dns/rdata/generic/nsec3_50.cc

@@ -129,9 +129,9 @@ NSEC3::NSEC3(const string& nsec3_str) :
 
 NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len) {
     // NSEC3 RR must have at least 5 octets:
-    // hash(1), flags(1), iteration(2), saltlen(1)
+    // hash algorithm(1), flags(1), iteration(2), saltlen(1)
     if (rdata_len < 5) {
-        isc_throw(InvalidRdataLength, "NSEC3 too short");
+        isc_throw(DNSMessageFORMERR, "NSEC3 too short, length: " << rdata_len);
     }
 
     const uint8_t hashalg = buffer.readUint8();
@@ -140,30 +140,26 @@ NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len) {
 
     const uint8_t saltlen = buffer.readUint8();
     rdata_len -= 5;
-
     if (rdata_len < saltlen) {
-        isc_throw(InvalidRdataLength, "NSEC3 salt too short");
+        isc_throw(DNSMessageFORMERR, "NSEC3 salt length is too large: " <<
+                  static_cast<unsigned int>(saltlen));
     }
 
     vector<uint8_t> salt(saltlen);
     buffer.readData(&salt[0], saltlen);
     rdata_len -= saltlen;
 
-    uint8_t nextlen = buffer.readUint8();
+    const uint8_t nextlen = buffer.readUint8();
     --rdata_len;
-
-    if (rdata_len < nextlen) {
-        isc_throw(InvalidRdataLength, "NSEC3 next hash too short");
+    if (rdata_len <= nextlen) {
+        isc_throw(DNSMessageFORMERR, "NSEC3 hash length is too large: " <<
+                  static_cast<unsigned int>(nextlen));
     }
 
     vector<uint8_t> next(nextlen);
     buffer.readData(&next[0], nextlen);
     rdata_len -= nextlen;
 
-    if (rdata_len == 0) {
-        isc_throw(InvalidRdataLength, "NSEC3 type bitmap too short");
-    }
-
     vector<uint8_t> typebits(rdata_len);
     buffer.readData(&typebits[0], rdata_len);
     buildRRTypeBitmap("NSEC3", rdata_len, typebits);

+ 27 - 3
src/lib/dns/tests/rdata_nsec3_unittest.cc

@@ -90,10 +90,10 @@ TEST_F(Rdata_NSEC3_Test, createFromWire) {
                   *rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
                                         "rdata_nsec3_fromWire1")));
 
-    // Too short RDLENGTH
+    // Too short RDLENGTH: it doesn't even contain the first 5 octets.
     EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                                      "rdata_nsec3_fromWire2"),
-                 InvalidRdataLength);
+                                      "rdata_nsec3_fromWire2.wire"),
+                 DNSMessageFORMERR);
 
     // These tests are the same as NSEC tests.  See the NSEC cases for
     // details.
@@ -121,6 +121,30 @@ TEST_F(Rdata_NSEC3_Test, createFromWire) {
     EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
                                       "rdata_nsec3_fromWire10.wire"),
                  DNSMessageFORMERR);
+
+    // salt length is too large
+    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
+                                      "rdata_nsec3_fromWire11.wire"),
+                 DNSMessageFORMERR);
+
+    // hash length is too large
+    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
+                                      "rdata_nsec3_fromWire12.wire"),
+                 DNSMessageFORMERR);
+
+    //
+    // Short buffer cases.  The data is valid NSEC3 RDATA, but the buffer
+    // is trimmed at the end.  All cases should result in an exception from
+    // the buffer class.
+    vector<uint8_t> data;
+    UnitTestUtil::readWireData("rdata_nsec3_fromWire1", data);
+    const uint16_t rdlen = (data.at(0) << 8) + data.at(1);
+    for (int i = 0; i < rdlen; ++i) {
+        // intentionally construct a short buffer
+        InputBuffer b(&data[0] + 2, i);
+        EXPECT_THROW(createRdata(RRType::NSEC3(), RRClass::IN(), b, 39),
+                     InvalidBufferPosition);
+    }
 }
 
 TEST_F(Rdata_NSEC3_Test, toWireRenderer) {

+ 9 - 6
src/lib/dns/tests/testdata/Makefile.am

@@ -8,13 +8,15 @@ BUILT_SOURCES += rdata_nsec_fromWire4.wire rdata_nsec_fromWire5.wire
 BUILT_SOURCES += rdata_nsec_fromWire6.wire rdata_nsec_fromWire7.wire
 BUILT_SOURCES += rdata_nsec_fromWire8.wire rdata_nsec_fromWire9.wire
 BUILT_SOURCES += rdata_nsec_fromWire10.wire
+BUILT_SOURCES += rdata_nsec3_fromWire2.wire
 BUILT_SOURCES += rdata_nsec3_fromWire4.wire rdata_nsec3_fromWire5.wire
 BUILT_SOURCES += rdata_nsec3_fromWire6.wire rdata_nsec3_fromWire7.wire
 BUILT_SOURCES += rdata_nsec3_fromWire8.wire rdata_nsec3_fromWire9.wire
-BUILT_SOURCES += rdata_nsec3_fromWire10.wire
+BUILT_SOURCES += rdata_nsec3_fromWire10.wire rdata_nsec3_fromWire11.wire
+BUILT_SOURCES += rdata_nsec3_fromWire12.wire
 BUILT_SOURCES += rdata_rrsig_fromWire2.wire
 BUILT_SOURCES += rdata_soa_toWireUncompressed.wire
-BUILT_SOURCES +=  rdata_txt_fromWire2.wire rdata_txt_fromWire3.wire
+BUILT_SOURCES += rdata_txt_fromWire2.wire rdata_txt_fromWire3.wire
 BUILT_SOURCES += rdata_txt_fromWire4.wire rdata_txt_fromWire5.wire
 BUILT_SOURCES += rdata_tsig_fromWire1.wire rdata_tsig_fromWire2.wire
 BUILT_SOURCES += rdata_tsig_fromWire3.wire rdata_tsig_fromWire4.wire
@@ -48,17 +50,18 @@ EXTRA_DIST += question_fromWire question_toWire1 question_toWire2
 EXTRA_DIST += rdata_cname_fromWire rdata_dname_fromWire rdata_dnskey_fromWire
 EXTRA_DIST += rdata_ds_fromWire rdata_in_a_fromWire rdata_in_aaaa_fromWire
 EXTRA_DIST += rdata_mx_fromWire rdata_mx_toWire1 rdata_ns_fromWire
-EXTRA_DIST += rdata_nsec3_fromWire1 rdata_nsec3_fromWire2 rdata_nsec3_fromWire3
-EXTRA_DIST += rdata_nsec3param_fromWire1 rdata_nsec_fromWire1
-EXTRA_DIST += rdata_nsec_fromWire2 rdata_nsec_fromWire3
+EXTRA_DIST += rdata_nsec_fromWire1 rdata_nsec_fromWire2 rdata_nsec_fromWire3
 EXTRA_DIST += rdata_nsec_fromWire4.spec rdata_nsec_fromWire5.spec
 EXTRA_DIST += rdata_nsec_fromWire6.spec rdata_nsec_fromWire7.spec
 EXTRA_DIST += rdata_nsec_fromWire8.spec rdata_nsec_fromWire9.spec
 EXTRA_DIST += rdata_nsec_fromWire10.spec
+EXTRA_DIST += rdata_nsec3param_fromWire1
+EXTRA_DIST += rdata_nsec3_fromWire1 rdata_nsec3_fromWire2 rdata_nsec3_fromWire3
 EXTRA_DIST += rdata_nsec3_fromWire4.spec rdata_nsec3_fromWire5.spec
 EXTRA_DIST += rdata_nsec3_fromWire6.spec rdata_nsec3_fromWire7.spec
 EXTRA_DIST += rdata_nsec3_fromWire8.spec rdata_nsec3_fromWire9.spec
-EXTRA_DIST += rdata_nsec3_fromWire10.spec
+EXTRA_DIST += rdata_nsec3_fromWire10.spec rdata_nsec3_fromWire11.spec
+EXTRA_DIST += rdata_nsec3_fromWire12.spec
 EXTRA_DIST += rdata_opt_fromWire rdata_rrsig_fromWire1
 EXTRA_DIST += rdata_rrsig_fromWire2.spec
 EXTRA_DIST += rdata_soa_fromWire rdata_soa_toWireUncompressed.spec

+ 8 - 0
src/lib/dns/tests/testdata/rdata_nsec3_fromWire11.spec

@@ -0,0 +1,8 @@
+#
+# An invalid NSEC3 RDATA: Saltlen is too large
+#
+
+[custom]
+sections: nsec3
+[nsec3]
+rdlen: 7

+ 9 - 0
src/lib/dns/tests/testdata/rdata_nsec3_fromWire12.spec

@@ -0,0 +1,9 @@
+#
+# An invalid NSEC3 RDATA: Hash length is too large
+#
+
+[custom]
+sections: nsec3
+[nsec3]
+# only contains the first byte of hash
+rdlen: 12

+ 0 - 12
src/lib/dns/tests/testdata/rdata_nsec3_fromWire2

@@ -1,12 +0,0 @@
-#
-# NSEC3 RDATA with a bogus RDLEN (too short)
-#
-
-# RDLENGTH, 29 bytes (should be 39)
-00 1e
-
-# NSEC3 record:
-# 1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6 NS SOA RRSIG DNSKEY NSEC3PARAM
-01 01 00 01 04 d3 99 ea ab 14 8a 77 c7 ac ef cb
-c5 54 46 03 2b 2d 96 1c c5 eb 68 21 ef 26 00 07
-22 00 00 00 00 02 90

+ 9 - 0
src/lib/dns/tests/testdata/rdata_nsec3_fromWire2.spec

@@ -0,0 +1,9 @@
+#
+# A malformed NSEC3 RDATA: RDLEN indicates it doesn't even contain the fixed
+# 5 octects
+#
+
+[custom]
+sections: nsec3
+[nsec3]
+rdlen: 4