Browse Source

[trac117] add a new test and code for too long hash. also add a trivial
public method to the NSEC3 class, getNext() primarily for the test
(but it would be useful more practical purposes, too).

JINMEI Tatuya 14 years ago
parent
commit
a9944090a8

+ 10 - 1
src/lib/dns/rdata/generic/nsec3_50.cc

@@ -102,6 +102,10 @@ NSEC3::NSEC3(const string& nsec3_str) :
 
 
     vector<uint8_t> next;
     vector<uint8_t> next;
     decodeBase32Hex(nexthash, next);
     decodeBase32Hex(nexthash, next);
+    if (next.size() > 255) {
+        isc_throw(InvalidRdataText, "NSEC3 hash is too long: "
+                  << next.size() << " bytes");
+    }
 
 
     stringstream bitmap_stream(bitmaps.str());
     stringstream bitmap_stream(bitmaps.str());
     uint8_t bitmap[8 * 1024];       // 64k bits
     uint8_t bitmap[8 * 1024];       // 64k bits
@@ -329,10 +333,15 @@ NSEC3::getIterations() const {
     return (impl_->iterations_);
     return (impl_->iterations_);
 }
 }
 
 
-vector<uint8_t>&
+const vector<uint8_t>&
 NSEC3::getSalt() const {
 NSEC3::getSalt() const {
     return (impl_->salt_);
     return (impl_->salt_);
 }
 }
 
 
+const vector<uint8_t>&
+NSEC3::getNext() const {
+    return (impl_->next_);
+}
+
 // END_RDATA_NAMESPACE
 // END_RDATA_NAMESPACE
 // END_ISC_NAMESPACE
 // END_ISC_NAMESPACE

+ 2 - 1
src/lib/dns/rdata/generic/nsec3_50.h

@@ -43,7 +43,8 @@ public:
     uint8_t getHashalg() const;
     uint8_t getHashalg() const;
     uint8_t getFlags() const;
     uint8_t getFlags() const;
     uint16_t getIterations() const;
     uint16_t getIterations() const;
-    std::vector<uint8_t>& getSalt() const;
+    const std::vector<uint8_t>& getSalt() const;
+    const std::vector<uint8_t>& getNext() const;
 
 
 private:
 private:
     NSEC3Impl* impl_;
     NSEC3Impl* impl_;

+ 13 - 0
src/lib/dns/tests/rdata_nsec3_unittest.cc

@@ -65,6 +65,12 @@ TEST_F(Rdata_NSEC3_Test, fromText) {
     EXPECT_EQ(255, generic::NSEC3("1 1 1 " + string(255 * 2, '0') +
     EXPECT_EQ(255, generic::NSEC3("1 1 1 " + string(255 * 2, '0') +
                                   " H9RSFB7FPF2L8HG35CMPC765TDK23RP6 "
                                   " H9RSFB7FPF2L8HG35CMPC765TDK23RP6 "
                                   "NS").getSalt().size());
                                   "NS").getSalt().size());
+
+    // hash that has the possible max length (see badText about the magic
+    // numbers)
+    EXPECT_EQ(255, generic::NSEC3("1 1 1 D399EAAB " +
+                                  string((255 * 8) / 5, '0') +
+                                  " NS").getNext().size());
 }
 }
 
 
 TEST_F(Rdata_NSEC3_Test, toText) {
 TEST_F(Rdata_NSEC3_Test, toText) {
@@ -109,6 +115,13 @@ TEST_F(Rdata_NSEC3_Test, badText) {
     EXPECT_THROW(generic::NSEC3("1 1 1 " + string(256 * 2, '0') +
     EXPECT_THROW(generic::NSEC3("1 1 1 " + string(256 * 2, '0') +
                                 " H9RSFB7FPF2L8HG35CMPC765TDK23RP6 NS"),
                                 " H9RSFB7FPF2L8HG35CMPC765TDK23RP6 NS"),
                  InvalidRdataText);
                  InvalidRdataText);
+
+    // Hash is too long.  Max = 255 bytes, base32-hex converts each 5 bytes
+    // of the original to 8 characters, so 260 * 8 / 5 is the smallest length
+    // of the encoded string that exceeds the max and doesn't require padding.
+    EXPECT_THROW(generic::NSEC3("1 1 1 D399EAAB " + string((260 * 8) / 5, '0') +
+                                " NS"),
+                 InvalidRdataText);
 }
 }
 
 
 TEST_F(Rdata_NSEC3_Test, createFromWire) {
 TEST_F(Rdata_NSEC3_Test, createFromWire) {