Browse Source

[2165] Don't continue and render RRSIGs if data is truncated

Mukund Sivaraman 12 years ago
parent
commit
2fabaed6bb

+ 9 - 0
src/lib/dns/rrset.cc

@@ -263,6 +263,10 @@ RRset::toWire(OutputBuffer& buffer) const {
     unsigned int rrs_written;
 
     rrs_written = rrsetToWire<OutputBuffer>(*this, buffer, 0);
+    if (getRdataCount() > rrs_written) {
+        return (rrs_written);
+    }
+
     if (rrsig_) {
         rrs_written += rrsetToWire<OutputBuffer>(*(rrsig_.get()), buffer, 0);
     }
@@ -277,6 +281,11 @@ RRset::toWire(AbstractMessageRenderer& renderer) const {
     rrs_written =
         rrsetToWire<AbstractMessageRenderer>(*this, renderer,
                                              renderer.getLengthLimit());
+    if (getRdataCount() > rrs_written) {
+        renderer.setTruncated();
+        return (rrs_written);
+    }
+
     if (rrsig_) {
         rrs_written +=
             rrsetToWire<AbstractMessageRenderer>(*(rrsig_.get()), renderer,

+ 48 - 0
src/lib/dns/tests/message_unittest.cc

@@ -770,6 +770,54 @@ TEST_F(MessageTest, toWireSigned) {
                         renderer.getLength(), &data[0], data.size());
 }
 
+TEST_F(MessageTest, toWireSignedAndTruncated) {
+    // EDNSPtr edns(new EDNS());
+    // edns->setUDPSize(256);
+    // message_render.setEDNS(edns);
+
+    message_render.setQid(0x75c1);
+    message_render.setOpcode(Opcode::QUERY());
+    message_render.setRcode(Rcode::NOERROR());
+    message_render.setHeaderFlag(Message::HEADERFLAG_QR, true);
+    message_render.setHeaderFlag(Message::HEADERFLAG_RD, true);
+    message_render.setHeaderFlag(Message::HEADERFLAG_AA, true);
+    message_render.addQuestion(Question(Name("test.example.com"), RRClass::IN(),
+                                        RRType::TXT()));
+
+    RRsetPtr rrset_txt = RRsetPtr(new RRset(test_name, RRClass::IN(),
+                                            RRType::TXT(), RRTTL(3600)));
+    rrset_txt->addRdata(generic::TXT(string(255, 'a')));
+    rrset_txt->addRdata(generic::TXT(string(255, 'b')));
+    rrset_txt->addRdata(generic::TXT(string(255, 'c')));
+    rrset_txt->addRdata(generic::TXT(string(255, 'd')));
+    rrset_txt->addRdata(generic::TXT(string(255, 'e')));
+    rrset_txt->addRdata(generic::TXT(string(255, 'f')));
+    rrset_txt->addRdata(generic::TXT(string(255, 'g')));
+    rrset_txt->addRdata(generic::TXT(string(255, 'h')));
+
+    rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
+                                     RRType::RRSIG(), RRTTL(3600)));
+    // one signature algorithm (5 = RSA/SHA-1)
+    rrset_rrsig->addRdata(generic::RRSIG("TXT 5 3 3600 "
+                                         "20000101000000 20000201000000 "
+                                         "12345 example.com. FAKEFAKEFAKE"));
+    rrset_txt->addRRsig(rrset_rrsig);
+    EXPECT_EQ(1, rrset_txt->getRRsigDataCount());
+
+    message_render.addRRset(Message::SECTION_ANSWER, rrset_txt);
+
+    EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION));
+    EXPECT_EQ(9, message_render.getRRCount(Message::SECTION_ANSWER));
+    EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_AUTHORITY));
+    EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL));
+
+    message_render.toWire(renderer);
+    vector<unsigned char> data;
+    UnitTestUtil::readWireData("message_toWire7", data);
+    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+                        renderer.getLength(), &data[0], data.size());
+}
+
 TEST_F(MessageTest, toWireInParseMode) {
     // toWire() isn't allowed in the parse mode.
     EXPECT_THROW(message_parse.toWire(renderer), InvalidMessageOperation);

+ 1 - 1
src/lib/dns/tests/testdata/Makefile.am

@@ -87,7 +87,7 @@ EXTRA_DIST += message_fromWire19.spec message_fromWire20.spec
 EXTRA_DIST += message_fromWire21.spec message_fromWire22.spec
 EXTRA_DIST += message_toWire1 message_toWire2.spec message_toWire3.spec
 EXTRA_DIST += message_toWire4.spec message_toWire5.spec
-EXTRA_DIST += message_toWire6
+EXTRA_DIST += message_toWire6 message_toWire7
 EXTRA_DIST += message_toText1.txt message_toText1.spec
 EXTRA_DIST += message_toText2.txt message_toText2.spec
 EXTRA_DIST += message_toText3.txt message_toText3.spec

+ 52 - 0
src/lib/dns/tests/testdata/message_toWire7

@@ -0,0 +1,52 @@
+#
+# A simple DNS query message (with a signed response)
+# ID = 0x75c1
+# QR=1 (response), Opcode=0, AA=1, RD=1 (other fields are 0)
+# QDCOUNT=1, ANCOUNT=2, ADCOUNT=1
+# Question: test.example.com. IN TXT
+# Answer:
+#  test.example.com. 3600 IN TXT aaaaa...
+#
+75c1 8700
+0001 0001 0000 0000
+#(4) t  e  s  t (7) e  x  a  m  p  l  e (3) c  o  m  .
+ 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00
+0010 0001
+# same name, fully compressed
+c0 0c
+# TTL=3600, TXT, IN, RDLENGTH=256, RDATA
+0010 0001 00000e10 0100 ff
+# 'a' repeated 255 times
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
+
+# ----- used while developing, commented out here:
+
+# # signature
+# # same name
+# c0 0c
+# # RRSIG, IN, TTL=3600, RDLENGTH=0x28 TYPE_COV=A ALGO=5 (RSA/SHA-1) LABELS=3 ORIG_TTL=3600
+# 002e 0001 00000e10 0028 0010 05 03 00000e10
+# # SIG_EXPIRY=20000101000000 SIG_INCEP=20000201000000 KEY_ID=12345
+# 386d4380 38962200 3039
+# #(7) e  x  a  m  p  l  e (3) c  o  m  .
+#  07 65 78 61 6d 70 6c 65 03 63 6f 6d 00
+# # FAKEFAKEFAKE
+# 14 02 84 14 02 84 14 02 84
+
+# # NAME = <root> (0), TYPE=OPT(EDNS0), PAYLOAD=256
+# 00 0029 0100 00 00 0000 00 00