BIND 10 trac3036, updated. 3e90051aa1a97eb1c450ba223ef2659220e97a45 [3036] Added a function which creates DHCID from DUID and FQDN.
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Jul 23 16:20:14 UTC 2013
The branch, trac3036 has been updated
via 3e90051aa1a97eb1c450ba223ef2659220e97a45 (commit)
from 76aa17ae5f1b89efac30211da457196d79ab49e4 (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 3e90051aa1a97eb1c450ba223ef2659220e97a45
Author: Marcin Siodelski <marcin at isc.org>
Date: Tue Jul 23 18:19:44 2013 +0200
[3036] Added a function which creates DHCID from DUID and FQDN.
-----------------------------------------------------------------------
Summary of changes:
src/bin/d2/Makefile.am | 2 +-
src/bin/d2/ncr_msg.cc | 57 +++++++++++++++++++++++++++++++++++++
src/bin/d2/ncr_msg.h | 16 +++++++++++
src/bin/d2/tests/ncr_unittests.cc | 39 +++++++++++++++++++++++++
4 files changed, 113 insertions(+), 1 deletion(-)
-----------------------------------------------------------------------
diff --git a/src/bin/d2/Makefile.am b/src/bin/d2/Makefile.am
index a00bece..b1c4c5e 100644
--- a/src/bin/d2/Makefile.am
+++ b/src/bin/d2/Makefile.am
@@ -2,7 +2,7 @@ SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
-AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += $(BOOST_INCLUDES) $(BOTAN_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_CLANGPP
diff --git a/src/bin/d2/ncr_msg.cc b/src/bin/d2/ncr_msg.cc
index cf47176..6d9115f 100644
--- a/src/bin/d2/ncr_msg.cc
+++ b/src/bin/d2/ncr_msg.cc
@@ -16,6 +16,8 @@
#include <asiolink/io_address.h>
#include <asiolink/io_error.h>
+#include <botan/sha2_32.h>
+
#include <sstream>
#include <limits>
@@ -31,6 +33,12 @@ D2Dhcid::D2Dhcid(const std::string& data) {
fromStr(data);
}
+D2Dhcid::D2Dhcid(const isc::dhcp::DUID& duid,
+ const std::vector<uint8_t>& wire_fqdn) {
+ fromDUID(duid, wire_fqdn);
+}
+
+
void
D2Dhcid::fromStr(const std::string& data) {
bytes_.clear();
@@ -44,8 +52,57 @@ D2Dhcid::fromStr(const std::string& data) {
std::string
D2Dhcid::toStr() const {
return (isc::util::encode::encodeHex(bytes_));
+}
+void
+D2Dhcid::fromDUID(const isc::dhcp::DUID& duid,
+ const std::vector<uint8_t>& wire_fqdn) {
+ // DHCID created from DUID starts with two bytes representing
+ // a type of the identifier. The value of 0x0002 indicates that
+ // DHCID has been created from DUID. The 3rd byte is equal to 1
+ // which indicates that the SHA-256 algorithm is used to create
+ // a DHCID digest. This value is called digest-type.
+ static uint8_t dhcid_header[] = { 0x00, 0x02, 0x01 };
+
+ // We get FQDN in the wire format, so we don't know if it is
+ // valid. It is caller's responsibility to make sure it is in
+ // the valid format. Here we just make sure it is not empty.
+ if (wire_fqdn.empty()) {
+ isc_throw(isc::d2::NcrMessageError,
+ "empty FQDN used to create DHCID");
+ }
+
+ // Get the wire representation of the DUID.
+ std::vector<uint8_t> data = duid.getDuid();
+ // It should be DUID class responsibility to validate the DUID
+ // but let's be on the safe side here and make sure that empty
+ // DUID is not returned.
+ if (data.empty()) {
+ isc_throw(isc::d2::NcrMessageError,
+ "empty DUID used to create DHCID");
+ }
+
+ // Append FQDN in the wire format.
+ data.insert(data.end(), wire_fqdn.begin(), wire_fqdn.end());
+
+ // Use the DUID and FQDN to compute the digest (see RFC4701, section 3).
+ Botan::SecureVector<Botan::byte> secure;
+ try {
+ Botan::SHA_256 sha;
+ // We have checked already that the DUID and FQDN aren't empty
+ // so it is safe to assume that the data buffer is not empty.
+ secure = sha.process(static_cast<const Botan::byte*>(&data[0]),
+ data.size());
+ } catch (const std::exception& ex) {
+ isc_throw(isc::d2::NcrMessageError,
+ "error while generating DHCID from DUID: "
+ << ex.what());
+ }
+ // The exception unsafe part is finished, so we can finally replace
+ // the contents of bytes_.
+ bytes_.assign(dhcid_header, dhcid_header + sizeof(dhcid_header));
+ bytes_.insert(bytes_.end(), secure.begin(), secure.end());
}
diff --git a/src/bin/d2/ncr_msg.h b/src/bin/d2/ncr_msg.h
index b3a4153..42a5ea4 100644
--- a/src/bin/d2/ncr_msg.h
+++ b/src/bin/d2/ncr_msg.h
@@ -21,6 +21,7 @@
/// DHCP-DDNS. These requests are referred to as NameChangeRequests.
#include <cc/data.h>
+#include <dhcp/duid.h>
#include <exceptions/exceptions.h>
#include <util/buffer.h>
#include <util/encode/hex.h>
@@ -77,6 +78,14 @@ public:
/// or there is an odd number of digits.
D2Dhcid(const std::string& data);
+ /// @brief Constructor, creates an instance of the @c D2Dhcid from the
+ /// @c isc::dhcp::DUID.
+ ///
+ /// @param duid An object representing DUID.
+ /// @param wire_fqdn A on-wire canonical representation of the FQDN.
+ D2Dhcid(const isc::dhcp::DUID& duid,
+ const std::vector<uint8_t>& wire_fqdn);
+
/// @brief Returns the DHCID value as a string of hexadecimal digits.
///
/// @return returns a string containing a contiguous stream of digits.
@@ -92,6 +101,13 @@ public:
/// or there is an odd number of digits.
void fromStr(const std::string& data);
+ /// @brief Sets the DHCID value based on the DUID.
+ ///
+ /// @param duid A @c isc::dhcp::DUID object encapsulating DUID.
+ /// @param wire_fqdn A on-wire canonical representation of the FQDN.
+ void fromDUID(const isc::dhcp::DUID& duid,
+ const std::vector<uint8_t>& wire_fqdn);
+
/// @brief Returns a reference to the DHCID byte vector.
///
/// @return returns a reference to the vector.
diff --git a/src/bin/d2/tests/ncr_unittests.cc b/src/bin/d2/tests/ncr_unittests.cc
index 8c7a9ac..da81a0d 100644
--- a/src/bin/d2/tests/ncr_unittests.cc
+++ b/src/bin/d2/tests/ncr_unittests.cc
@@ -13,6 +13,7 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <d2/ncr_msg.h>
+#include <dhcp/duid.h>
#include <util/time_utilities.h>
#include <gtest/gtest.h>
@@ -21,6 +22,7 @@
using namespace std;
using namespace isc;
using namespace isc::d2;
+using namespace isc::dhcp;
namespace {
@@ -273,6 +275,43 @@ TEST(NameChangeRequestTest, dhcidTest) {
EXPECT_EQ(test_str, next_str);
}
+/// Tests that DHCID is correctly created from a DUID and FQDN. The final format
+/// of the DHCID is as follows:
+/// <identifier-type> <digest-type-code> <digest>
+/// where:
+/// - identifier-type (2 octets) is 0x0002.
+/// - digest-type-code (1 octet) indicates SHA-256 hashing and is equal 0x1.
+/// - digest = SHA-256(<DUID> <FQDN>)
+/// Note: FQDN is given in the on-wire canonical format.
+TEST(NameChangeRequestTest, dhcidFromDUID) {
+ D2Dhcid dhcid;
+
+ // Create DUID.
+ uint8_t duid_data[] = { 0, 1, 2, 3, 4, 5, 6 };
+ DUID duid(duid_data, sizeof(duid_data));
+
+ // Create FQDN in on-wire format: myhost.example.com. It is encoded
+ // as a set of labels, each preceded by its length. The whole FQDN
+ // is zero-terminated.
+ const uint8_t fqdn_data[] = {
+ 6, 109, 121, 104, 111, 115, 116, // myhost.
+ 7, 101, 120, 97, 109, 112, 108, 101, // example.
+ 3, 99, 111, 109, 0 // com.
+ };
+ std::vector<uint8_t> wire_fqdn(fqdn_data, fqdn_data + sizeof(fqdn_data));
+
+ // Create DHCID.
+ ASSERT_NO_THROW(dhcid.fromDUID(duid, wire_fqdn));
+
+ // The reference DHCID (represented as string of hexadecimal digits)
+ // has been calculated using one of the online calculators.
+ std::string dhcid_ref = "0002012191B7B21AF97E0E656DF887C5E2D"
+ "EF30E7758A207EDF4CCB2DE8CA37066021C";
+
+ // Make sure that the DHCID is valid.
+ EXPECT_EQ(dhcid_ref, dhcid.toStr());
+}
+
/// @brief Verifies the fundamentals of converting from and to JSON.
/// It verifies that:
/// 1. A NameChangeRequest can be created from a valid JSON string.
More information about the bind10-changes
mailing list