From: Mukund Sivaraman Date: Wed, 25 Jul 2012 07:04:19 +0000 (+0530) Subject: [2124] Handle empty SSHFP fingerprints X-Git-Tag: trac2351_base~170 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b82a4fda312a144d2883de96da76386ec199eea;p=thirdparty%2Fkea.git [2124] Handle empty SSHFP fingerprints --- diff --git a/src/lib/dns/rdata/generic/sshfp_44.cc b/src/lib/dns/rdata/generic/sshfp_44.cc index b183180b64..4c221b8161 100644 --- a/src/lib/dns/rdata/generic/sshfp_44.cc +++ b/src/lib/dns/rdata/generic/sshfp_44.cc @@ -56,8 +56,6 @@ SSHFP::SSHFP(InputBuffer& buffer, size_t rdata_len) { SSHFP::SSHFP(const std::string& sshfp_str) { std::istringstream iss(sshfp_str); - // peekc should be of iss's char_type for isspace to work - std::istringstream::char_type peekc; std::stringbuf fingerprintbuf; uint32_t algorithm, fingerprint_type; @@ -74,21 +72,16 @@ SSHFP::SSHFP(const std::string& sshfp_str) { isc_throw(InvalidRdataText, "SSHFP fingerprint type out of range"); } - iss.read(&peekc, 1); - if (!iss.good() || !isspace(peekc, iss.getloc())) { - isc_throw(InvalidRdataText, "SSHFP presentation format error"); - } - iss >> &fingerprintbuf; - - algorithm_ = algorithm; - fingerprint_type_ = fingerprint_type; - try { decodeHex(fingerprintbuf.str(), fingerprint_); } catch (const isc::BadValue& e) { - isc_throw(InvalidRdataText, "Bad SSHFP fingerprint: " << e.what()); + isc_throw(InvalidRdataText, + "Bad SSHFP fingerprint: " << e.what()); } + + algorithm_ = algorithm; + fingerprint_type_ = fingerprint_type; } SSHFP::SSHFP(uint8_t algorithm, uint8_t fingerprint_type, @@ -114,14 +107,20 @@ void SSHFP::toWire(OutputBuffer& buffer) const { buffer.writeUint8(algorithm_); buffer.writeUint8(fingerprint_type_); - buffer.writeData(&fingerprint_[0], fingerprint_.size()); + + if (fingerprint_.size() > 0) { + buffer.writeData(&fingerprint_[0], fingerprint_.size()); + } } void SSHFP::toWire(AbstractMessageRenderer& renderer) const { renderer.writeUint8(algorithm_); renderer.writeUint8(fingerprint_type_); - renderer.writeData(&fingerprint_[0], fingerprint_.size()); + + if (fingerprint_.size() > 0) { + renderer.writeData(&fingerprint_[0], fingerprint_.size()); + } } string @@ -172,5 +171,10 @@ SSHFP::getSSHFPFingerprintType() const { return (fingerprint_type_); } +size_t +SSHFP::getFingerprintLen() const { + return (fingerprint_.size()); +} + // END_RDATA_NAMESPACE // END_ISC_NAMESPACE diff --git a/src/lib/dns/rdata/generic/sshfp_44.h b/src/lib/dns/rdata/generic/sshfp_44.h index c3ba944df9..fadff33eb9 100644 --- a/src/lib/dns/rdata/generic/sshfp_44.h +++ b/src/lib/dns/rdata/generic/sshfp_44.h @@ -40,6 +40,7 @@ public: /// uint8_t getSSHFPAlgorithmNumber() const; uint8_t getSSHFPFingerprintType() const; + size_t getFingerprintLen() const; private: /// Note: this is a prototype version; we may reconsider diff --git a/src/lib/dns/tests/rdata_sshfp_unittest.cc b/src/lib/dns/tests/rdata_sshfp_unittest.cc index 8c493a4ed1..8adc963191 100644 --- a/src/lib/dns/tests/rdata_sshfp_unittest.cc +++ b/src/lib/dns/tests/rdata_sshfp_unittest.cc @@ -41,6 +41,18 @@ class Rdata_SSHFP_Test : public RdataTest { const string sshfp_txt("2 1 123456789abcdef67890123456789abcdef67890"); const generic::SSHFP rdata_sshfp(2, 1, "123456789abcdef67890123456789abcdef67890"); +const uint8_t rdata_sshfp_wiredata[] = { + // algorithm + 0x02, + // fingerprint type + 0x01, + // fingerprint + 0x12, 0x34, 0x56, 0x78, + 0x9a, 0xbc, 0xde, 0xf6, + 0x78, 0x90, 0x12, 0x34, + 0x56, 0x78, 0x9a, 0xbc, + 0xde, 0xf6, 0x78, 0x90 +}; TEST_F(Rdata_SSHFP_Test, createFromText) { // Basic test @@ -84,7 +96,6 @@ TEST_F(Rdata_SSHFP_Test, algorithmTypes) { TEST_F(Rdata_SSHFP_Test, badText) { EXPECT_THROW(const generic::SSHFP rdata_sshfp("1"), InvalidRdataText); - EXPECT_THROW(const generic::SSHFP rdata_sshfp("1 2"), InvalidRdataText); EXPECT_THROW(const generic::SSHFP rdata_sshfp("BUCKLE MY SHOES"), InvalidRdataText); EXPECT_THROW(const generic::SSHFP rdata_sshfp("1 2 foo bar"), InvalidRdataText); } @@ -147,6 +158,18 @@ TEST_F(Rdata_SSHFP_Test, toText) { EXPECT_TRUE(boost::iequals(sshfp_txt, rdata_sshfp.toText())); } +TEST_F(Rdata_SSHFP_Test, toWire) { + this->obuffer.clear(); + rdata_sshfp.toWire(this->obuffer); + + EXPECT_EQ(22, this->obuffer.getLength()); + + EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, + this->obuffer.getData(), + this->obuffer.getLength(), + rdata_sshfp_wiredata, sizeof(rdata_sshfp_wiredata)); +} + TEST_F(Rdata_SSHFP_Test, getSSHFPAlgorithmNumber) { EXPECT_EQ(2, rdata_sshfp.getSSHFPAlgorithmNumber()); } @@ -154,4 +177,27 @@ TEST_F(Rdata_SSHFP_Test, getSSHFPAlgorithmNumber) { TEST_F(Rdata_SSHFP_Test, getSSHFPFingerprintType) { EXPECT_EQ(1, rdata_sshfp.getSSHFPFingerprintType()); } + +TEST_F(Rdata_SSHFP_Test, getFingerprintLen) { + EXPECT_EQ(20, rdata_sshfp.getFingerprintLen()); +} + +TEST_F(Rdata_SSHFP_Test, emptyFingerprintFromWire) { + const generic::SSHFP& rdf = + dynamic_cast + (*rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire12")); + + EXPECT_EQ(4, rdf.getSSHFPAlgorithmNumber()); + EXPECT_EQ(9, rdf.getSSHFPFingerprintType()); + EXPECT_EQ(0, rdf.getFingerprintLen()); +} + +TEST_F(Rdata_SSHFP_Test, emptyFingerprintFromString) { + const generic::SSHFP rdata_sshfp2("5 6"); + + EXPECT_EQ(5, rdata_sshfp2.getSSHFPAlgorithmNumber()); + EXPECT_EQ(6, rdata_sshfp2.getSSHFPFingerprintType()); + EXPECT_EQ(0, rdata_sshfp2.getFingerprintLen()); +} } diff --git a/src/lib/dns/tests/testdata/Makefile.am b/src/lib/dns/tests/testdata/Makefile.am index 77308a7310..93528339a1 100644 --- a/src/lib/dns/tests/testdata/Makefile.am +++ b/src/lib/dns/tests/testdata/Makefile.am @@ -136,7 +136,7 @@ EXTRA_DIST += rdata_sshfp_fromWire3.spec rdata_sshfp_fromWire4.spec EXTRA_DIST += rdata_sshfp_fromWire5.spec rdata_sshfp_fromWire6.spec EXTRA_DIST += rdata_sshfp_fromWire7.spec rdata_sshfp_fromWire8.spec EXTRA_DIST += rdata_sshfp_fromWire9 rdata_sshfp_fromWire10 -EXTRA_DIST += rdata_sshfp_fromWire11 +EXTRA_DIST += rdata_sshfp_fromWire11 rdata_sshfp_fromWire12 EXTRA_DIST += rdata_afsdb_fromWire1.spec rdata_afsdb_fromWire2.spec EXTRA_DIST += rdata_afsdb_fromWire3.spec rdata_afsdb_fromWire4.spec EXTRA_DIST += rdata_afsdb_fromWire5.spec diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire12 b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire12 new file mode 100644 index 0000000000..eabd06b97f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire12 @@ -0,0 +1,4 @@ +# SSHFP RDATA, RDLEN=02 +0002 +# ALGORITHM=4 FINGERPRINT_TYPE=9 +04 09