diff options
author | Mukund Sivaraman <muks@isc.org> | 2014-02-11 06:31:27 +0100 |
---|---|---|
committer | Mukund Sivaraman <muks@isc.org> | 2014-02-11 06:44:21 +0100 |
commit | 506b5310b54aa834f2a1dcdff167f91a07b974fa (patch) | |
tree | 92b4e757da04e4e803efd4d7a1671832a1e451ba | |
parent | [2185] Add tests for RdataPimplHolder (diff) | |
download | kea-506b5310b54aa834f2a1dcdff167f91a07b974fa.tar.xz kea-506b5310b54aa834f2a1dcdff167f91a07b974fa.zip |
[2185] Don't allow empty TLSA certificate association data
-rw-r--r-- | src/lib/dns/rdata/generic/tlsa_52.cc | 59 | ||||
-rw-r--r-- | src/lib/dns/tests/rdata_tlsa_unittest.cc | 77 |
2 files changed, 46 insertions, 90 deletions
diff --git a/src/lib/dns/rdata/generic/tlsa_52.cc b/src/lib/dns/rdata/generic/tlsa_52.cc index a896e8d47f..774bdef6cf 100644 --- a/src/lib/dns/rdata/generic/tlsa_52.cc +++ b/src/lib/dns/rdata/generic/tlsa_52.cc @@ -89,16 +89,16 @@ TLSA::constructFromLexer(MasterLexer& lexer) { } lexer.ungetToken(); + if (certificate_assoc_data.empty()) { + isc_throw(InvalidRdataText, "Empty TLSA certificate association data"); + } + vector<uint8_t> data; - // If certificate association data is missing, it's OK. See the API - // documentation of the constructor. - if (certificate_assoc_data.size() > 0) { - try { - decodeHex(certificate_assoc_data, data); - } catch (const isc::BadValue& e) { - isc_throw(InvalidRdataText, - "Bad TLSA certificate association data: " << e.what()); - } + try { + decodeHex(certificate_assoc_data, data); + } catch (const isc::BadValue& e) { + isc_throw(InvalidRdataText, + "Bad TLSA certificate association data: " << e.what()); } return (new TLSAImpl(certificate_usage, selector, matching_type, data)); @@ -187,18 +187,26 @@ TLSA::TLSA(InputBuffer& buffer, size_t rdata_len) { vector<uint8_t> data; rdata_len -= 3; - if (rdata_len > 0) { - data.resize(rdata_len); - buffer.readData(&data[0], rdata_len); + + if (rdata_len == 0) { + isc_throw(InvalidRdataLength, + "Empty TLSA certificate association data"); } + data.resize(rdata_len); + buffer.readData(&data[0], rdata_len); + impl_ = new TLSAImpl(certificate_usage, selector, matching_type, data); } TLSA::TLSA(uint8_t certificate_usage, uint8_t selector, - uint8_t matching_type, const std::string& certificate_assoc_data) : + uint8_t matching_type, const std::string& certificate_assoc_data) : impl_(NULL) { + if (certificate_assoc_data.empty()) { + isc_throw(InvalidRdataText, "Empty TLSA certificate association data"); + } + vector<uint8_t> data; try { decodeHex(certificate_assoc_data, data); @@ -237,10 +245,10 @@ TLSA::toWire(OutputBuffer& buffer) const { buffer.writeUint8(impl_->selector_); buffer.writeUint8(impl_->matching_type_); - if (!impl_->data_.empty()) { - buffer.writeData(&impl_->data_[0], - impl_->data_.size()); - } + // The constructors must ensure that the certificate association + // data field is not empty. + assert(!impl_->data_.empty()); + buffer.writeData(&impl_->data_[0], impl_->data_.size()); } void @@ -249,19 +257,22 @@ TLSA::toWire(AbstractMessageRenderer& renderer) const { renderer.writeUint8(impl_->selector_); renderer.writeUint8(impl_->matching_type_); - if (!impl_->data_.empty()) { - renderer.writeData(&impl_->data_[0], - impl_->data_.size()); - } + // The constructors must ensure that the certificate association + // data field is not empty. + assert(!impl_->data_.empty()); + renderer.writeData(&impl_->data_[0], impl_->data_.size()); } string TLSA::toText() const { + // The constructors must ensure that the certificate association + // data field is not empty. + assert(!impl_->data_.empty()); + return (lexical_cast<string>(static_cast<int>(impl_->certificate_usage_)) + " " + lexical_cast<string>(static_cast<int>(impl_->selector_)) + " " + - lexical_cast<string>(static_cast<int>(impl_->matching_type_)) + - (impl_->data_.empty() ? "" : - " " + encodeHex(impl_->data_))); + lexical_cast<string>(static_cast<int>(impl_->matching_type_)) + " " + + encodeHex(impl_->data_)); } int diff --git a/src/lib/dns/tests/rdata_tlsa_unittest.cc b/src/lib/dns/tests/rdata_tlsa_unittest.cc index 3e494c2623..b1129afc70 100644 --- a/src/lib/dns/tests/rdata_tlsa_unittest.cc +++ b/src/lib/dns/tests/rdata_tlsa_unittest.cc @@ -217,6 +217,11 @@ TEST_F(Rdata_TLSA_Test, createFromWire) { "rdata_tlsa_fromWire10"), InvalidBufferPosition); + // certificate association data is empty + EXPECT_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire12"), + InvalidRdataLength); + // all RDATA is missing EXPECT_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), "rdata_tlsa_fromWire11"), @@ -228,17 +233,14 @@ TEST_F(Rdata_TLSA_Test, createFromParams) { 0, 0, 1, "d2abde240d7cd3ee6b4b28c54df034b9" "7983a1d16e8a410e4561cb106618e971"); EXPECT_EQ(0, rdata_tlsa2.compare(rdata_tlsa)); + + // empty certificate association data should throw + EXPECT_THROW(const generic::TLSA rdata_tlsa2(0, 0, 1, ""), + InvalidRdataText); } TEST_F(Rdata_TLSA_Test, toText) { EXPECT_TRUE(boost::iequals(tlsa_txt, rdata_tlsa.toText())); - - const string tlsa_txt2("3 2 1"); - const generic::TLSA rdata_tlsa2(tlsa_txt2); - EXPECT_TRUE(boost::iequals(tlsa_txt2, rdata_tlsa2.toText())); - - const generic::TLSA rdata_tlsa3("3 2 1 "); - EXPECT_TRUE(boost::iequals(tlsa_txt2, rdata_tlsa3.toText())); } TEST_F(Rdata_TLSA_Test, toWire) { @@ -255,7 +257,8 @@ TEST_F(Rdata_TLSA_Test, toWire) { } TEST_F(Rdata_TLSA_Test, compare) { - const generic::TLSA rdata_tlsa2("0 0 0"); + const generic::TLSA rdata_tlsa2("0 0 0 d2abde240d7cd3ee6b4b28c54df034b9" + "7983a1d16e8a410e4561cb106618e971"); EXPECT_EQ(-1, rdata_tlsa2.compare(rdata_tlsa)); EXPECT_EQ(1, rdata_tlsa.compare(rdata_tlsa2)); } @@ -275,62 +278,4 @@ TEST_F(Rdata_TLSA_Test, getMatchingType) { TEST_F(Rdata_TLSA_Test, getDataLength) { EXPECT_EQ(32, rdata_tlsa.getDataLength()); } - -TEST_F(Rdata_TLSA_Test, emptyCertificateAssociationDataFromWire) { - const uint8_t rdf_wiredata[] = { - // certificate usage - 0x03, - // selector - 0x01, - // matching type - 0x02, - }; - - const generic::TLSA rdf = - dynamic_cast<const generic::TLSA&> - (*rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), - "rdata_tlsa_fromWire12")); - - EXPECT_EQ(3, rdf.getCertificateUsage()); - EXPECT_EQ(1, rdf.getSelector()); - EXPECT_EQ(2, rdf.getMatchingType()); - EXPECT_EQ(0, rdf.getDataLength()); - - this->obuffer.clear(); - rdf.toWire(this->obuffer); - - EXPECT_EQ(3, this->obuffer.getLength()); - - EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, - this->obuffer.getData(), - this->obuffer.getLength(), - rdf_wiredata, sizeof(rdf_wiredata)); -} - -TEST_F(Rdata_TLSA_Test, emptyCertificateAssociationDataFromString) { - const generic::TLSA rdata_tlsa2("3 2 1"); - const uint8_t rdata_tlsa2_wiredata[] = { - // certificate usage - 0x03, - // selector - 0x02, - // matching type - 0x01 - }; - - EXPECT_EQ(3, rdata_tlsa2.getCertificateUsage()); - EXPECT_EQ(2, rdata_tlsa2.getSelector()); - EXPECT_EQ(1, rdata_tlsa2.getMatchingType()); - EXPECT_EQ(0, rdata_tlsa2.getDataLength()); - - this->obuffer.clear(); - rdata_tlsa2.toWire(this->obuffer); - - EXPECT_EQ(3, this->obuffer.getLength()); - - EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, - this->obuffer.getData(), - this->obuffer.getLength(), - rdata_tlsa2_wiredata, sizeof(rdata_tlsa2_wiredata)); -} } |