BIND 10 master, updated. f93e6fba92ae4d4d62a130b0b6398dd7e7508fa0 [master] Add ChangeLog for #2185
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Feb 19 14:03:09 UTC 2014
The branch, master has been updated
via f93e6fba92ae4d4d62a130b0b6398dd7e7508fa0 (commit)
via a168170430f6927f28597b2a6debebe31cf39b13 (commit)
via 080f7d6b93825785ebdca4aaa64df2f636d4e54a (commit)
via fa62fc571faa4207a06261138326aadf2c9153fb (commit)
via 569e7f0737f69d0c2768bdc02f0b0961e992a24c (commit)
via 506b5310b54aa834f2a1dcdff167f91a07b974fa (commit)
via 5813a6de50708cb1d0a738afa56d0adbd6ba23da (commit)
via 9ac39be69c035539d8bca28d3a5e6dd5d0d2ef19 (commit)
via d88bd0463689b5d44ff6617ce080bb75f256bf96 (commit)
from 670577e8ed19eea6e5a679d030faea7c2f8641e1 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit f93e6fba92ae4d4d62a130b0b6398dd7e7508fa0
Author: Mukund Sivaraman <muks at isc.org>
Date: Wed Feb 19 19:24:31 2014 +0530
[master] Add ChangeLog for #2185
commit a168170430f6927f28597b2a6debebe31cf39b13
Merge: 670577e 080f7d6
Author: Mukund Sivaraman <muks at isc.org>
Date: Wed Feb 19 19:23:16 2014 +0530
Merge branch 'trac2185'
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 4 +
src/lib/dns/Makefile.am | 3 +
src/lib/dns/gen-rdatacode.py.in | 2 +-
src/lib/dns/rdata/generic/tlsa_52.cc | 350 ++++++++++++++++++++
.../dns/rdata/generic/{sshfp_44.h => tlsa_52.h} | 33 +-
.../nsec3hash_python.h => rdata_pimpl_holder.h} | 59 ++--
src/lib/dns/tests/Makefile.am | 2 +
src/lib/dns/tests/rdata_pimpl_holder_unittest.cc | 62 ++++
src/lib/dns/tests/rdata_tlsa_unittest.cc | 282 ++++++++++++++++
src/lib/dns/tests/testdata/.gitignore | 6 +
src/lib/dns/tests/testdata/Makefile.am | 9 +
src/lib/dns/tests/testdata/rdata_tlsa_fromWire | 4 +
src/lib/dns/tests/testdata/rdata_tlsa_fromWire10 | 6 +
...data_sshfp_fromWire11 => rdata_tlsa_fromWire11} | 4 +-
src/lib/dns/tests/testdata/rdata_tlsa_fromWire12 | 4 +
src/lib/dns/tests/testdata/rdata_tlsa_fromWire2 | 4 +
.../dns/tests/testdata/rdata_tlsa_fromWire3.spec | 7 +
.../dns/tests/testdata/rdata_tlsa_fromWire4.spec | 7 +
.../dns/tests/testdata/rdata_tlsa_fromWire5.spec | 7 +
.../dns/tests/testdata/rdata_tlsa_fromWire6.spec | 7 +
.../dns/tests/testdata/rdata_tlsa_fromWire7.spec | 9 +
.../dns/tests/testdata/rdata_tlsa_fromWire8.spec | 7 +
src/lib/dns/tests/testdata/rdata_tlsa_fromWire9 | 7 +
src/lib/util/python/gen_wiredata.py.in | 28 +-
24 files changed, 870 insertions(+), 43 deletions(-)
create mode 100644 src/lib/dns/rdata/generic/tlsa_52.cc
copy src/lib/dns/rdata/generic/{sshfp_44.h => tlsa_52.h} (67%)
copy src/lib/dns/{python/nsec3hash_python.h => rdata_pimpl_holder.h} (53%)
create mode 100644 src/lib/dns/tests/rdata_pimpl_holder_unittest.cc
create mode 100644 src/lib/dns/tests/rdata_tlsa_unittest.cc
create mode 100644 src/lib/dns/tests/testdata/rdata_tlsa_fromWire
create mode 100644 src/lib/dns/tests/testdata/rdata_tlsa_fromWire10
copy src/lib/dns/tests/testdata/{rdata_sshfp_fromWire11 => rdata_tlsa_fromWire11} (59%)
create mode 100644 src/lib/dns/tests/testdata/rdata_tlsa_fromWire12
create mode 100644 src/lib/dns/tests/testdata/rdata_tlsa_fromWire2
create mode 100644 src/lib/dns/tests/testdata/rdata_tlsa_fromWire3.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_tlsa_fromWire4.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_tlsa_fromWire5.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_tlsa_fromWire6.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_tlsa_fromWire7.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_tlsa_fromWire8.spec
create mode 100644 src/lib/dns/tests/testdata/rdata_tlsa_fromWire9
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 78ea162..626850b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+754. [func] muks
+ Add support for the TLSA RR type (RFC 6698).
+ (Trac #2185, git a168170430f6927f28597b2a6debebe31cf39b13)
+
753. [func] muks
libdns++: the unknown/generic (RFC 3597) RDATA class now uses the
generic lexer in constructors from text.
diff --git a/src/lib/dns/Makefile.am b/src/lib/dns/Makefile.am
index ede699a..2c57b5d 100644
--- a/src/lib/dns/Makefile.am
+++ b/src/lib/dns/Makefile.am
@@ -70,6 +70,8 @@ EXTRA_DIST += rdata/generic/spf_99.cc
EXTRA_DIST += rdata/generic/spf_99.h
EXTRA_DIST += rdata/generic/sshfp_44.cc
EXTRA_DIST += rdata/generic/sshfp_44.h
+EXTRA_DIST += rdata/generic/tlsa_52.cc
+EXTRA_DIST += rdata/generic/tlsa_52.h
EXTRA_DIST += rdata/generic/txt_16.cc
EXTRA_DIST += rdata/generic/txt_16.h
EXTRA_DIST += rdata/generic/minfo_14.cc
@@ -135,6 +137,7 @@ libb10_dns___la_SOURCES += master_loader.h
libb10_dns___la_SOURCES += rrset_collection_base.h
libb10_dns___la_SOURCES += rrset_collection.h rrset_collection.cc
libb10_dns___la_SOURCES += zone_checker.h zone_checker.cc
+libb10_dns___la_SOURCES += rdata_pimpl_holder.h
libb10_dns___la_SOURCES += rdata/generic/detail/char_string.h
libb10_dns___la_SOURCES += rdata/generic/detail/char_string.cc
libb10_dns___la_SOURCES += rdata/generic/detail/nsec_bitmap.h
diff --git a/src/lib/dns/gen-rdatacode.py.in b/src/lib/dns/gen-rdatacode.py.in
index 3fd3b33..0c5bdf4 100755
--- a/src/lib/dns/gen-rdatacode.py.in
+++ b/src/lib/dns/gen-rdatacode.py.in
@@ -41,7 +41,7 @@ meta_types = {
'10': 'null', '11': 'wks', '19': 'x25', '21': 'rt', '22': 'nsap',
'23': 'nsap-ptr', '24': 'sig', '20': 'isdn', '25': 'key', '26': 'px',
'27': 'gpos', '29': 'loc', '36': 'kx', '37': 'cert', '42': 'apl',
- '45': 'ipseckey', '52': 'tlsa', '55': 'hip', '103': 'unspec',
+ '45': 'ipseckey', '55': 'hip', '103': 'unspec',
'104': 'nid', '105': 'l32', '106': 'l64', '107': 'lp', '249': 'tkey',
'253': 'mailb', '256': 'uri', '257': 'caa'
}
diff --git a/src/lib/dns/rdata/generic/tlsa_52.cc b/src/lib/dns/rdata/generic/tlsa_52.cc
new file mode 100644
index 0000000..774bdef
--- /dev/null
+++ b/src/lib/dns/rdata/generic/tlsa_52.cc
@@ -0,0 +1,350 @@
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+
+#include <boost/lexical_cast.hpp>
+
+#include <exceptions/exceptions.h>
+
+#include <util/buffer.h>
+#include <util/encode/hex.h>
+#include <dns/name.h>
+#include <dns/messagerenderer.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+#include <dns/rdata_pimpl_holder.h>
+
+using namespace std;
+using boost::lexical_cast;
+using namespace isc::util;
+using namespace isc::util::encode;
+
+// BEGIN_ISC_NAMESPACE
+// BEGIN_RDATA_NAMESPACE
+
+struct TLSAImpl {
+ // straightforward representation of TLSA RDATA fields
+ TLSAImpl(uint8_t certificate_usage, uint8_t selector,
+ uint8_t matching_type, const vector<uint8_t>& data) :
+ certificate_usage_(certificate_usage),
+ selector_(selector),
+ matching_type_(matching_type),
+ data_(data)
+ {}
+
+ uint8_t certificate_usage_;
+ uint8_t selector_;
+ uint8_t matching_type_;
+ const vector<uint8_t> data_;
+};
+
+// helper function for string and lexer constructors
+TLSAImpl*
+TLSA::constructFromLexer(MasterLexer& lexer) {
+ const uint32_t certificate_usage =
+ lexer.getNextToken(MasterToken::NUMBER).getNumber();
+ if (certificate_usage > 255) {
+ isc_throw(InvalidRdataText,
+ "TLSA certificate usage field out of range");
+ }
+
+ const uint32_t selector =
+ lexer.getNextToken(MasterToken::NUMBER).getNumber();
+ if (selector > 255) {
+ isc_throw(InvalidRdataText,
+ "TLSA selector field out of range");
+ }
+
+ const uint32_t matching_type =
+ lexer.getNextToken(MasterToken::NUMBER).getNumber();
+ if (matching_type > 255) {
+ isc_throw(InvalidRdataText,
+ "TLSA matching type field out of range");
+ }
+
+ std::string certificate_assoc_data;
+ std::string data_substr;
+ while (true) {
+ const MasterToken& token =
+ lexer.getNextToken(MasterToken::STRING, true);
+ if ((token.getType() == MasterToken::END_OF_FILE) ||
+ (token.getType() == MasterToken::END_OF_LINE)) {
+ break;
+ }
+
+ token.getString(data_substr);
+ certificate_assoc_data.append(data_substr);
+ }
+ lexer.ungetToken();
+
+ if (certificate_assoc_data.empty()) {
+ isc_throw(InvalidRdataText, "Empty TLSA certificate association data");
+ }
+
+ vector<uint8_t> data;
+ 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));
+}
+
+/// \brief Constructor from string.
+///
+/// The given string must represent a valid TLSA RDATA. There can be
+/// extra space characters at the beginning or end of the text (which
+/// are simply ignored), but other extra text, including a new line,
+/// will make the construction fail with an exception.
+///
+/// The Certificate Usage, Selector and Matching Type fields must be
+/// within their valid ranges, but are not constrained to the values
+/// defined in RFC6698.
+///
+/// The Certificate Association Data Field field may be absent, but if
+/// present it must contain a valid hex encoding of the data. Whitespace
+/// is allowed in the hex text.
+///
+/// \throw InvalidRdataText if any fields are missing, out of their
+/// valid ranges, or are incorrect, or Certificate Association Data is
+/// not a valid hex string.
+///
+/// \param tlsa_str A string containing the RDATA to be created
+TLSA::TLSA(const string& tlsa_str) :
+ impl_(NULL)
+{
+ // We use a smart pointer here because if there is an exception in
+ // this constructor, the destructor is not called and there could be
+ // a leak of the TLSAImpl that constructFromLexer() returns.
+ RdataPimplHolder<TLSAImpl> impl_ptr;
+
+ try {
+ std::istringstream ss(tlsa_str);
+ MasterLexer lexer;
+ lexer.pushSource(ss);
+
+ impl_ptr.reset(constructFromLexer(lexer));
+
+ if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
+ isc_throw(InvalidRdataText, "extra input text for TLSA: "
+ << tlsa_str);
+ }
+ } catch (const MasterLexer::LexerError& ex) {
+ isc_throw(InvalidRdataText, "Failed to construct TLSA from '" <<
+ tlsa_str << "': " << ex.what());
+ }
+
+ impl_ = impl_ptr.release();
+}
+
+/// \brief Constructor with a context of MasterLexer.
+///
+/// The \c lexer should point to the beginning of valid textual representation
+/// of an TLSA RDATA.
+///
+/// \throw MasterLexer::LexerError General parsing error such as missing field.
+/// \throw InvalidRdataText Fields are out of their valid range, or are
+/// incorrect, or Certificate Association Data is not a valid hex string.
+///
+/// \param lexer A \c MasterLexer object parsing a master file for the
+/// RDATA to be created
+TLSA::TLSA(MasterLexer& lexer, const Name*,
+ MasterLoader::Options, MasterLoaderCallbacks&) :
+ impl_(constructFromLexer(lexer))
+{
+}
+
+/// \brief Constructor from InputBuffer.
+///
+/// The passed buffer must contain a valid TLSA RDATA.
+///
+/// The Certificate Usage, Selector and Matching Type fields must be
+/// within their valid ranges, but are not constrained to the values
+/// defined in RFC6698. It is okay for the certificate association data
+/// to be missing (see the description of the constructor from string).
+TLSA::TLSA(InputBuffer& buffer, size_t rdata_len) {
+ if (rdata_len < 3) {
+ isc_throw(InvalidRdataLength, "TLSA record too short");
+ }
+
+ const uint8_t certificate_usage = buffer.readUint8();
+ const uint8_t selector = buffer.readUint8();
+ const uint8_t matching_type = buffer.readUint8();
+
+ vector<uint8_t> data;
+ rdata_len -= 3;
+
+ 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) :
+ 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);
+ } catch (const isc::BadValue& e) {
+ isc_throw(InvalidRdataText,
+ "Bad TLSA certificate association data: " << e.what());
+ }
+
+ impl_ = new TLSAImpl(certificate_usage, selector, matching_type, data);
+}
+
+TLSA::TLSA(const TLSA& other) :
+ Rdata(), impl_(new TLSAImpl(*other.impl_))
+{}
+
+TLSA&
+TLSA::operator=(const TLSA& source) {
+ if (this == &source) {
+ return (*this);
+ }
+
+ TLSAImpl* newimpl = new TLSAImpl(*source.impl_);
+ delete impl_;
+ impl_ = newimpl;
+
+ return (*this);
+}
+
+TLSA::~TLSA() {
+ delete impl_;
+}
+
+void
+TLSA::toWire(OutputBuffer& buffer) const {
+ buffer.writeUint8(impl_->certificate_usage_);
+ buffer.writeUint8(impl_->selector_);
+ buffer.writeUint8(impl_->matching_type_);
+
+ // 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
+TLSA::toWire(AbstractMessageRenderer& renderer) const {
+ renderer.writeUint8(impl_->certificate_usage_);
+ renderer.writeUint8(impl_->selector_);
+ renderer.writeUint8(impl_->matching_type_);
+
+ // 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_)) + " " +
+ encodeHex(impl_->data_));
+}
+
+int
+TLSA::compare(const Rdata& other) const {
+ const TLSA& other_tlsa = dynamic_cast<const TLSA&>(other);
+
+ if (impl_->certificate_usage_ < other_tlsa.impl_->certificate_usage_) {
+ return (-1);
+ } else if (impl_->certificate_usage_ >
+ other_tlsa.impl_->certificate_usage_) {
+ return (1);
+ }
+
+ if (impl_->selector_ < other_tlsa.impl_->selector_) {
+ return (-1);
+ } else if (impl_->selector_ > other_tlsa.impl_->selector_) {
+ return (1);
+ }
+
+ if (impl_->matching_type_ < other_tlsa.impl_->matching_type_) {
+ return (-1);
+ } else if (impl_->matching_type_ >
+ other_tlsa.impl_->matching_type_) {
+ return (1);
+ }
+
+ const size_t this_len = impl_->data_.size();
+ const size_t other_len = other_tlsa.impl_->data_.size();
+ const size_t cmplen = min(this_len, other_len);
+
+ if (cmplen > 0) {
+ const int cmp = memcmp(&impl_->data_[0],
+ &other_tlsa.impl_->data_[0],
+ cmplen);
+ if (cmp != 0) {
+ return (cmp);
+ }
+ }
+
+ if (this_len == other_len) {
+ return (0);
+ } else if (this_len < other_len) {
+ return (-1);
+ } else {
+ return (1);
+ }
+}
+
+uint8_t
+TLSA::getCertificateUsage() const {
+ return (impl_->certificate_usage_);
+}
+
+uint8_t
+TLSA::getSelector() const {
+ return (impl_->selector_);
+}
+
+uint8_t
+TLSA::getMatchingType() const {
+ return (impl_->matching_type_);
+}
+
+const std::vector<uint8_t>&
+TLSA::getData() const {
+ return (impl_->data_);
+}
+
+size_t
+TLSA::getDataLength() const {
+ return (impl_->data_.size());
+}
+
+// END_RDATA_NAMESPACE
+// END_ISC_NAMESPACE
diff --git a/src/lib/dns/rdata/generic/tlsa_52.h b/src/lib/dns/rdata/generic/tlsa_52.h
new file mode 100644
index 0000000..7d8c69a
--- /dev/null
+++ b/src/lib/dns/rdata/generic/tlsa_52.h
@@ -0,0 +1,65 @@
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// BEGIN_HEADER_GUARD
+
+#include <stdint.h>
+
+#include <dns/name.h>
+#include <dns/rdata.h>
+
+#include <string>
+#include <vector>
+
+// BEGIN_ISC_NAMESPACE
+
+// BEGIN_COMMON_DECLARATIONS
+// END_COMMON_DECLARATIONS
+
+// BEGIN_RDATA_NAMESPACE
+
+struct TLSAImpl;
+
+class TLSA : public Rdata {
+public:
+ // BEGIN_COMMON_MEMBERS
+ // END_COMMON_MEMBERS
+
+ TLSA(uint8_t certificate_usage, uint8_t selector,
+ uint8_t matching_type, const std::string& certificate_assoc_data);
+ TLSA& operator=(const TLSA& source);
+ ~TLSA();
+
+ ///
+ /// Specialized methods
+ ///
+ uint8_t getCertificateUsage() const;
+ uint8_t getSelector() const;
+ uint8_t getMatchingType() const;
+ const std::vector<uint8_t>& getData() const;
+ size_t getDataLength() const;
+
+private:
+ TLSAImpl* constructFromLexer(MasterLexer& lexer);
+
+ TLSAImpl* impl_;
+};
+
+// END_RDATA_NAMESPACE
+// END_ISC_NAMESPACE
+// END_HEADER_GUARD
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/lib/dns/rdata_pimpl_holder.h b/src/lib/dns/rdata_pimpl_holder.h
new file mode 100644
index 0000000..2705dd8
--- /dev/null
+++ b/src/lib/dns/rdata_pimpl_holder.h
@@ -0,0 +1,60 @@
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef DNS_RDATA_PIMPL_HOLDER_H
+#define DNS_RDATA_PIMPL_HOLDER_H 1
+
+#include <boost/noncopyable.hpp>
+
+#include <cstddef> // for NULL
+
+namespace isc {
+namespace dns {
+namespace rdata {
+
+template <typename T>
+class RdataPimplHolder : boost::noncopyable {
+public:
+ RdataPimplHolder(T* obj = NULL) :
+ obj_(obj)
+ {}
+
+ ~RdataPimplHolder() {
+ delete obj_;
+ }
+
+ void reset(T* obj = NULL) {
+ delete obj_;
+ obj_ = obj;
+ }
+
+ T* get() {
+ return (obj_);
+ }
+
+ T* release() {
+ T* obj = obj_;
+ obj_ = NULL;
+ return (obj);
+ }
+
+private:
+ T* obj_;
+};
+
+} // namespace rdata
+} // namespace dns
+} // namespace isc
+
+#endif // DNS_RDATA_PIMPL_HOLDER_H
diff --git a/src/lib/dns/tests/Makefile.am b/src/lib/dns/tests/Makefile.am
index f982f88..0b8b70d 100644
--- a/src/lib/dns/tests/Makefile.am
+++ b/src/lib/dns/tests/Makefile.am
@@ -39,6 +39,7 @@ run_unittests_SOURCES += opcode_unittest.cc
run_unittests_SOURCES += rcode_unittest.cc
run_unittests_SOURCES += rdata_unittest.h rdata_unittest.cc
run_unittests_SOURCES += rdatafields_unittest.cc
+run_unittests_SOURCES += rdata_pimpl_holder_unittest.cc
run_unittests_SOURCES += rdata_char_string_unittest.cc
run_unittests_SOURCES += rdata_in_a_unittest.cc rdata_in_aaaa_unittest.cc
run_unittests_SOURCES += rdata_ns_unittest.cc rdata_soa_unittest.cc
@@ -60,6 +61,7 @@ run_unittests_SOURCES += rdata_nsec3param_like_unittest.cc
run_unittests_SOURCES += rdata_rrsig_unittest.cc
run_unittests_SOURCES += rdata_rp_unittest.cc
run_unittests_SOURCES += rdata_srv_unittest.cc
+run_unittests_SOURCES += rdata_tlsa_unittest.cc
run_unittests_SOURCES += rdata_minfo_unittest.cc
run_unittests_SOURCES += rdata_tsig_unittest.cc
run_unittests_SOURCES += rdata_naptr_unittest.cc
diff --git a/src/lib/dns/tests/rdata_pimpl_holder_unittest.cc b/src/lib/dns/tests/rdata_pimpl_holder_unittest.cc
new file mode 100644
index 0000000..96a03ba
--- /dev/null
+++ b/src/lib/dns/tests/rdata_pimpl_holder_unittest.cc
@@ -0,0 +1,62 @@
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <dns/rdata_pimpl_holder.h>
+
+#include <gtest/gtest.h>
+
+using namespace isc::dns::rdata;
+
+namespace {
+
+TEST(RdataPimplHolderTest, all) {
+ // Let's check with an integer
+ int* i1 = new int(42);
+ RdataPimplHolder<int> holder1(i1);
+ // The same pointer must be returned.
+ EXPECT_EQ(i1, holder1.get());
+ // Obviously the value should match too.
+ EXPECT_EQ(42, *holder1.get());
+ // We don't explictly delete i or holder1, so it should not leak
+ // anything when the test is done (checked by Valgrind).
+
+ // The following cases are similar:
+
+ // Test no-argument reset()
+ int* i2 = new int(43);
+ RdataPimplHolder<int> holder2(i2);
+ holder2.reset();
+ EXPECT_EQ(NULL, holder2.get());
+
+ // Test reset() with argument
+ int* i3 = new int(44);
+ int* i4 = new int(45);
+ RdataPimplHolder<int> holder3(i3);
+ EXPECT_EQ(i3, holder3.get());
+ holder3.reset(i4);
+ EXPECT_EQ(i4, holder3.get());
+ EXPECT_EQ(45, *holder3.get());
+
+ // Test release()
+ RdataPimplHolder<int> holder4(new int(46));
+ EXPECT_NE(static_cast<void*>(NULL), holder4.get());
+ EXPECT_EQ(46, *holder4.get());
+ int* i5 = holder4.release();
+ EXPECT_EQ(NULL, holder4.get());
+ EXPECT_NE(static_cast<void*>(NULL), i5);
+ EXPECT_EQ(46, *i5);
+ delete i5;
+}
+
+}
diff --git a/src/lib/dns/tests/rdata_tlsa_unittest.cc b/src/lib/dns/tests/rdata_tlsa_unittest.cc
new file mode 100644
index 0000000..30b608b
--- /dev/null
+++ b/src/lib/dns/tests/rdata_tlsa_unittest.cc
@@ -0,0 +1,282 @@
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <algorithm>
+#include <string>
+
+#include <util/buffer.h>
+#include <dns/messagerenderer.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+#include <dns/rrclass.h>
+#include <dns/rrtype.h>
+
+#include <gtest/gtest.h>
+
+#include <dns/tests/unittest_util.h>
+#include <dns/tests/rdata_unittest.h>
+#include <util/unittests/wiredata.h>
+
+#include <boost/algorithm/string.hpp>
+
+using namespace std;
+using namespace isc;
+using namespace isc::dns;
+using namespace isc::util;
+using namespace isc::dns::rdata;
+using isc::UnitTestUtil;
+using isc::util::unittests::matchWireData;
+
+namespace {
+class Rdata_TLSA_Test : public RdataTest {
+protected:
+ Rdata_TLSA_Test() :
+ tlsa_txt("0 0 1 d2abde240d7cd3ee6b4b28c54df034b9"
+ "7983a1d16e8a410e4561cb106618e971"),
+ rdata_tlsa(tlsa_txt)
+ {}
+
+ void checkFromText_None(const string& rdata_str) {
+ checkFromText<generic::TLSA, isc::Exception, isc::Exception>(
+ rdata_str, rdata_tlsa, false, false);
+ }
+
+ void checkFromText_InvalidText(const string& rdata_str) {
+ checkFromText<generic::TLSA, InvalidRdataText, InvalidRdataText>(
+ rdata_str, rdata_tlsa, true, true);
+ }
+
+ void checkFromText_LexerError(const string& rdata_str) {
+ checkFromText
+ <generic::TLSA, InvalidRdataText, MasterLexer::LexerError>(
+ rdata_str, rdata_tlsa, true, true);
+ }
+
+ void checkFromText_BadString(const string& rdata_str) {
+ checkFromText
+ <generic::TLSA, InvalidRdataText, isc::Exception>(
+ rdata_str, rdata_tlsa, true, false);
+ }
+
+ const string tlsa_txt;
+ const generic::TLSA rdata_tlsa;
+};
+
+const uint8_t rdata_tlsa_wiredata[] = {
+ // certificate usage
+ 0x00,
+ // selector
+ 0x00,
+ // matching type
+ 0x01,
+ // certificate association data
+ 0xd2, 0xab, 0xde, 0x24, 0x0d, 0x7c, 0xd3, 0xee,
+ 0x6b, 0x4b, 0x28, 0xc5, 0x4d, 0xf0, 0x34, 0xb9,
+ 0x79, 0x83, 0xa1, 0xd1, 0x6e, 0x8a, 0x41, 0x0e,
+ 0x45, 0x61, 0xcb, 0x10, 0x66, 0x18, 0xe9, 0x71
+};
+
+TEST_F(Rdata_TLSA_Test, createFromText) {
+ // Basic test
+ checkFromText_None(tlsa_txt);
+
+ // With different spacing
+ checkFromText_None("0 0 1 d2abde240d7cd3ee6b4b28c54df034b9"
+ "7983a1d16e8a410e4561cb106618e971");
+
+ // Combination of lowercase and uppercase
+ checkFromText_None("0 0 1 D2ABDE240D7CD3EE6B4B28C54DF034B9"
+ "7983a1d16e8a410e4561cb106618e971");
+
+ // spacing in the certificate association data field
+ checkFromText_None("0 0 1 d2abde240d7cd3ee6b4b28c54df034b9"
+ " 7983a1d16e8a410e4561cb106618e971");
+
+ // multi-line certificate association data field
+ checkFromText_None("0 0 1 ( d2abde240d7cd3ee6b4b28c54df034b9\n"
+ " 7983a1d16e8a410e4561cb106618e971 )");
+
+ // string constructor throws if there's extra text,
+ // but lexer constructor doesn't
+ checkFromText_BadString(tlsa_txt + "\n" + tlsa_txt);
+}
+
+TEST_F(Rdata_TLSA_Test, fields) {
+ // Some of these may not be RFC conformant, but we relax the check
+ // in our code to work with other field values that may show up in
+ // the future.
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("1 0 1 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("2 0 1 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("3 0 1 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("128 0 1 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("255 0 1 12ab"));
+
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 1 1 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 2 1 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 3 1 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 128 1 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 255 1 12ab"));
+
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 0 1 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 0 2 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 0 3 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 0 128 12ab"));
+ EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 0 255 12ab"));
+
+ // > 255 would be broken
+ EXPECT_THROW(const generic::TLSA rdata_tlsa("256 0 1 12ab"),
+ InvalidRdataText);
+ EXPECT_THROW(const generic::TLSA rdata_tlsa("0 256 1 12ab"),
+ InvalidRdataText);
+ EXPECT_THROW(const generic::TLSA rdata_tlsa("0 0 256 12ab"),
+ InvalidRdataText);
+}
+
+TEST_F(Rdata_TLSA_Test, badText) {
+ checkFromText_LexerError("1");
+ checkFromText_LexerError("ONE 2 3 123456789abcdef67890123456789abcdef67890");
+ checkFromText_LexerError("1 TWO 3 123456789abcdef67890123456789abcdef67890");
+ checkFromText_LexerError("1 2 THREE 123456789abcdef67890123456789abcdef67890");
+ checkFromText_InvalidText("1 2 3 BAABAABLACKSHEEP");
+ checkFromText_InvalidText(tlsa_txt + " extra text");
+
+ // yes, these are redundant to the last test cases in the .fields
+ // test
+ checkFromText_InvalidText(
+ "2345 1 2 123456789abcdef67890123456789abcdef67890");
+ checkFromText_InvalidText(
+ "3 1234 4 123456789abcdef67890123456789abcdef67890");
+ checkFromText_InvalidText(
+ "5 6 1234 123456789abcdef67890123456789abcdef67890");
+
+ // negative values are trapped in the lexer rather than the
+ // constructor
+ checkFromText_LexerError("-2 0 1 123456789abcdef67890123456789abcdef67890");
+ checkFromText_LexerError("0 -2 1 123456789abcdef67890123456789abcdef67890");
+ checkFromText_LexerError("0 0 -2 123456789abcdef67890123456789abcdef67890");
+}
+
+TEST_F(Rdata_TLSA_Test, copyAndAssign) {
+ // Copy construct
+ generic::TLSA rdata_tlsa2(rdata_tlsa);
+ EXPECT_EQ(0, rdata_tlsa.compare(rdata_tlsa2));
+
+ // Assignment, mainly to confirm it doesn't cause disruption.
+ rdata_tlsa2 = rdata_tlsa;
+ EXPECT_EQ(0, rdata_tlsa.compare(rdata_tlsa2));
+}
+
+TEST_F(Rdata_TLSA_Test, createFromWire) {
+ // Basic test
+ EXPECT_EQ(0, rdata_tlsa.compare(
+ *rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"),
+ "rdata_tlsa_fromWire")));
+ // Combination of lowercase and uppercase
+ EXPECT_EQ(0, rdata_tlsa.compare(
+ *rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"),
+ "rdata_tlsa_fromWire2")));
+ // certificate_usage=0, selector=0, matching_type=1
+ EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"),
+ "rdata_tlsa_fromWire3.wire"));
+
+ // certificate_usage=255, selector=0, matching_type=1
+ EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"),
+ "rdata_tlsa_fromWire4.wire"));
+
+ // certificate_usage=0, selector=255, matching_type=1
+ EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"),
+ "rdata_tlsa_fromWire5.wire"));
+
+ // certificate_usage=0, selector=0, matching_type=255
+ EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"),
+ "rdata_tlsa_fromWire6.wire"));
+
+ // certificate_usage=3, selector=1, matching_type=2
+ EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"),
+ "rdata_tlsa_fromWire7.wire"));
+
+ // short certificate association data
+ EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"),
+ "rdata_tlsa_fromWire8.wire"));
+
+ // certificate association data is shorter than rdata len
+ EXPECT_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"),
+ "rdata_tlsa_fromWire9"),
+ InvalidBufferPosition);
+
+ // certificate association data is missing
+ EXPECT_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"),
+ "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"),
+ InvalidBufferPosition);
+}
+
+TEST_F(Rdata_TLSA_Test, createFromParams) {
+ const generic::TLSA rdata_tlsa2(
+ 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()));
+}
+
+TEST_F(Rdata_TLSA_Test, toWire) {
+ this->obuffer.clear();
+ rdata_tlsa.toWire(this->obuffer);
+
+ EXPECT_EQ(sizeof (rdata_tlsa_wiredata),
+ this->obuffer.getLength());
+
+ matchWireData(rdata_tlsa_wiredata, sizeof(rdata_tlsa_wiredata),
+ obuffer.getData(), obuffer.getLength());
+}
+
+TEST_F(Rdata_TLSA_Test, compare) {
+ 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));
+}
+
+TEST_F(Rdata_TLSA_Test, getCertificateUsage) {
+ EXPECT_EQ(0, rdata_tlsa.getCertificateUsage());
+}
+
+TEST_F(Rdata_TLSA_Test, getSelector) {
+ EXPECT_EQ(0, rdata_tlsa.getSelector());
+}
+
+TEST_F(Rdata_TLSA_Test, getMatchingType) {
+ EXPECT_EQ(1, rdata_tlsa.getMatchingType());
+}
+
+TEST_F(Rdata_TLSA_Test, getDataLength) {
+ EXPECT_EQ(32, rdata_tlsa.getDataLength());
+}
+}
diff --git a/src/lib/dns/tests/testdata/.gitignore b/src/lib/dns/tests/testdata/.gitignore
index a0a14f4..8079354 100644
--- a/src/lib/dns/tests/testdata/.gitignore
+++ b/src/lib/dns/tests/testdata/.gitignore
@@ -87,6 +87,12 @@
/rdata_sshfp_fromWire6.wire
/rdata_sshfp_fromWire7.wire
/rdata_sshfp_fromWire8.wire
+/rdata_tlsa_fromWire3.wire
+/rdata_tlsa_fromWire4.wire
+/rdata_tlsa_fromWire5.wire
+/rdata_tlsa_fromWire6.wire
+/rdata_tlsa_fromWire7.wire
+/rdata_tlsa_fromWire8.wire
/rdata_tsig_fromWire1.wire
/rdata_tsig_fromWire2.wire
/rdata_tsig_fromWire3.wire
diff --git a/src/lib/dns/tests/testdata/Makefile.am b/src/lib/dns/tests/testdata/Makefile.am
index b6d7e35..15c3b3e 100644
--- a/src/lib/dns/tests/testdata/Makefile.am
+++ b/src/lib/dns/tests/testdata/Makefile.am
@@ -56,6 +56,9 @@ BUILT_SOURCES += rdata_afsdb_toWire1.wire rdata_afsdb_toWire2.wire
BUILT_SOURCES += rdata_soa_toWireUncompressed.wire
BUILT_SOURCES += rdata_txt_fromWire2.wire rdata_txt_fromWire3.wire
BUILT_SOURCES += rdata_txt_fromWire4.wire rdata_txt_fromWire5.wire
+BUILT_SOURCES += rdata_tlsa_fromWire3.wire rdata_tlsa_fromWire4.wire
+BUILT_SOURCES += rdata_tlsa_fromWire5.wire rdata_tlsa_fromWire6.wire
+BUILT_SOURCES += rdata_tlsa_fromWire7.wire rdata_tlsa_fromWire8.wire
BUILT_SOURCES += rdata_tsig_fromWire1.wire rdata_tsig_fromWire2.wire
BUILT_SOURCES += rdata_tsig_fromWire3.wire rdata_tsig_fromWire4.wire
BUILT_SOURCES += rdata_tsig_fromWire5.wire rdata_tsig_fromWire6.wire
@@ -159,6 +162,12 @@ EXTRA_DIST += rrcode16_fromWire1 rrcode16_fromWire2
EXTRA_DIST += rrcode32_fromWire1 rrcode32_fromWire2
EXTRA_DIST += rrset_toWire1 rrset_toWire2
EXTRA_DIST += rrset_toWire3 rrset_toWire4
+EXTRA_DIST += rdata_tlsa_fromWire rdata_tlsa_fromWire2
+EXTRA_DIST += rdata_tlsa_fromWire3.spec rdata_tlsa_fromWire4.spec
+EXTRA_DIST += rdata_tlsa_fromWire5.spec rdata_tlsa_fromWire6.spec
+EXTRA_DIST += rdata_tlsa_fromWire7.spec rdata_tlsa_fromWire8.spec
+EXTRA_DIST += rdata_tlsa_fromWire9 rdata_tlsa_fromWire10
+EXTRA_DIST += rdata_tlsa_fromWire11 rdata_tlsa_fromWire12
EXTRA_DIST += rdata_tsig_fromWire1.spec rdata_tsig_fromWire2.spec
EXTRA_DIST += rdata_tsig_fromWire3.spec rdata_tsig_fromWire4.spec
EXTRA_DIST += rdata_tsig_fromWire5.spec rdata_tsig_fromWire6.spec
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire
new file mode 100644
index 0000000..38e279c
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire
@@ -0,0 +1,4 @@
+# TLSA RDATA, RDLEN=35
+0023
+# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=...
+00 00 01 d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire10 b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire10
new file mode 100644
index 0000000..67cecb1
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire10
@@ -0,0 +1,6 @@
+# Test where certificate association data is missing.
+
+# TLSA RDATA, RDLEN=35
+0023
+# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=(missing)
+00 00 01
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire11 b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire11
new file mode 100644
index 0000000..4b8ec93
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire11
@@ -0,0 +1,4 @@
+# Test where RDATA is completely missing
+
+# TLSA RDATA, RDLEN=35
+0023
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire12 b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire12
new file mode 100644
index 0000000..71c7b9c
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire12
@@ -0,0 +1,4 @@
+# TLSA RDATA, RDLEN=3
+0003
+# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=(none)
+03 01 02
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire2 b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire2
new file mode 100644
index 0000000..36ce278
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire2
@@ -0,0 +1,4 @@
+# TLSA RDATA, RDLEN=35
+0023
+# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=...
+00 00 01 d2abde240d7cd3ee6b4b28c54df034b97983A1D16E8A410E4561CB106618E971
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire3.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire3.spec
new file mode 100644
index 0000000..39c8057
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire3.spec
@@ -0,0 +1,7 @@
+#
+# TLSA RDATA
+#
+[custom]
+sections: tlsa
+[tlsa]
+certificate_usage: 0
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire4.spec
new file mode 100644
index 0000000..d97ae6a
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire4.spec
@@ -0,0 +1,7 @@
+#
+# TLSA RDATA
+#
+[custom]
+sections: tlsa
+[tlsa]
+certificate_usage: 255
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire5.spec
new file mode 100644
index 0000000..cc3e296
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire5.spec
@@ -0,0 +1,7 @@
+#
+# TLSA RDATA
+#
+[custom]
+sections: tlsa
+[tlsa]
+selector: 255
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire6.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire6.spec
new file mode 100644
index 0000000..eed0ab9
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire6.spec
@@ -0,0 +1,7 @@
+#
+# TLSA RDATA
+#
+[custom]
+sections: tlsa
+[tlsa]
+matching_type: 255
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire7.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire7.spec
new file mode 100644
index 0000000..576df1e
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire7.spec
@@ -0,0 +1,9 @@
+#
+# TLSA RDATA
+#
+[custom]
+sections: tlsa
+[tlsa]
+certificate_usage: 3
+selector: 1
+matching_type: 2
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire8.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire8.spec
new file mode 100644
index 0000000..ef5c108
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire8.spec
@@ -0,0 +1,7 @@
+#
+# TLSA RDATA
+#
+[custom]
+sections: tlsa
+[tlsa]
+certificate_association_data: '0123'
diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire9 b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire9
new file mode 100644
index 0000000..fc4560a
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire9
@@ -0,0 +1,7 @@
+# Test where certificate association data length is smaller than what
+# RDATA length indicates.
+
+# TLSA RDATA, RDLEN=64
+0040
+# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=(32 bytes)
+00 00 01 d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971
diff --git a/src/lib/util/python/gen_wiredata.py.in b/src/lib/util/python/gen_wiredata.py.in
index b3858b6..1251f92 100755
--- a/src/lib/util/python/gen_wiredata.py.in
+++ b/src/lib/util/python/gen_wiredata.py.in
@@ -352,7 +352,7 @@ dict_rrtype = { 'none' : 0, 'a' : 1, 'ns' : 2, 'md' : 3, 'mf' : 4, 'cname' : 5,
'srv' : 33, 'naptr' : 35, 'kx' : 36, 'cert' : 37, 'a6' : 38,
'dname' : 39, 'opt' : 41, 'apl' : 42, 'ds' : 43, 'sshfp' : 44,
'ipseckey' : 45, 'rrsig' : 46, 'nsec' : 47, 'dnskey' : 48,
- 'dhcid' : 49, 'nsec3' : 50, 'nsec3param' : 51, 'hip' : 55,
+ 'dhcid' : 49, 'nsec3' : 50, 'nsec3param' : 51, 'tlsa' : 52, 'hip' : 55,
'spf' : 99, 'unspec' : 103, 'tkey' : 249, 'tsig' : 250,
'dlv' : 32769, 'ixfr' : 251, 'axfr' : 252, 'mailb' : 253,
'maila' : 254, 'any' : 255 }
@@ -1156,6 +1156,32 @@ class RRSIG(RR):
f.write('# Tag=%d Signer=%s and Signature\n' % (self.tag, self.signer))
f.write('%04x %s %s\n' % (self.tag, name_wire, sig_wire))
+class TLSA(RR):
+ '''Implements rendering TLSA RDATA in the test data format.
+
+ Configurable parameters are as follows (see the description of the
+ same name of attribute for the default value):
+ - certificate_usage (int): The certificate usage field value.
+ - selector (int): The selector field value.
+ - matching_type (int): The matching type field value.
+ - certificate_association_data (string): The certificate association data.
+ '''
+ certificate_usage = 0
+ selector = 0
+ matching_type = 1
+ certificate_association_data = 'd2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971'
+ def dump(self, f):
+ if self.rdlen is None:
+ self.rdlen = 2 + (len(self.certificate_association_data) / 2)
+ else:
+ self.rdlen = int(self.rdlen)
+ self.dump_header(f, self.rdlen)
+ f.write('# CERTIFICATE_USAGE=%d SELECTOR=%d MATCHING_TYPE=%d CERTIFICATE_ASSOCIATION_DATA=%s\n' %\
+ (self.certificate_usage, self.selector, self.matching_type,\
+ self.certificate_association_data))
+ f.write('%02x %02x %02x %s\n' % (self.certificate_usage, self.selector, self.matching_type,\
+ self.certificate_association_data))
+
class TSIG(RR):
'''Implements rendering TSIG RDATA in the test data format.
More information about the bind10-changes
mailing list