#include <util/hash/sha1.h>
#include <dns/name.h>
+#include <dns/labelsequence.h>
#include <dns/nsec3hash.h>
#include <dns/rdataclass.h>
#include <dns/name_internal.h>
}
virtual std::string calculate(const Name& name) const;
+ virtual std::string calculate(const LabelSequence& ls) const;
virtual bool match(const generic::NSEC3& nsec3) const;
virtual bool match(const generic::NSEC3PARAM& nsec3param) const;
const vector<uint8_t>& salt) const;
private:
+ std::string calculateForWiredata(const uint8_t* data, size_t length) const;
+
const uint8_t algorithm_;
const uint16_t iterations_;
uint8_t* salt_data_;
}
string
-NSEC3HashRFC5155::calculate(const Name& name) const {
+NSEC3HashRFC5155::calculateForWiredata(const uint8_t* data,
+ size_t length) const
+{
// We first need to normalize the name by converting all upper case
// characters in the labels to lower ones.
- obuf_.clear();
- name.toWire(obuf_);
uint8_t name_buf[256];
- assert(obuf_.getLength() < sizeof (name_buf));
+ assert(length < sizeof (name_buf));
- const uint8_t *p1 = static_cast<const uint8_t*>(obuf_.getData());
+ const uint8_t *p1 = data;
uint8_t *p2 = name_buf;
while (*p1 != 0) {
char len = *p1;
uint8_t* const digest = &digest_[0];
assert(digest_.size() == SHA1_HASHSIZE);
- iterateSHA1(&sha1_ctx_, name_buf, obuf_.getLength(),
+ iterateSHA1(&sha1_ctx_, name_buf, length,
salt_data_, salt_length_, digest);
for (unsigned int n = 0; n < iterations_; ++n) {
iterateSHA1(&sha1_ctx_, digest, SHA1_HASHSIZE,
return (encodeBase32Hex(digest_));
}
+string
+NSEC3HashRFC5155::calculate(const Name& name) const {
+ obuf_.clear();
+ name.toWire(obuf_);
+
+ return (calculateForWiredata(static_cast<const uint8_t*>(obuf_.getData()),
+ obuf_.getLength()));
+}
+
+string
+NSEC3HashRFC5155::calculate(const LabelSequence& ls) const {
+ assert(ls.isAbsolute());
+
+ size_t length;
+ const uint8_t* data = ls.getData(&length);
+
+ return (calculateForWiredata(data, length));
+}
+
bool
NSEC3HashRFC5155::match(uint8_t algorithm, uint16_t iterations,
const vector<uint8_t>& salt) const
namespace isc {
namespace dns {
class Name;
+class LabelSequence;
namespace rdata {
namespace generic {
/// \brief The destructor.
virtual ~NSEC3Hash() {}
- /// \brief Calculate the NSEC3 hash.
+ /// \brief Calculate the NSEC3 hash (Name variant).
///
/// This method calculates the NSEC3 hash value for the given \c name
/// with the hash parameters (algorithm, iterations and salt) given at
/// construction, and returns the value as a base32hex-encoded string
/// (without containing any white spaces). All US-ASCII letters in the
- /// string will be upper cased.
+ /// string will be lower cased.
///
/// \param name The domain name for which the hash value is to be
/// calculated.
/// \return Base32hex-encoded string of the hash value.
virtual std::string calculate(const Name& name) const = 0;
+ /// \brief Calculate the NSEC3 hash (LabelSequence variant).
+ ///
+ /// This method calculates the NSEC3 hash value for the given
+ /// absolute LabelSequence \c ls with the hash parameters
+ /// (algorithm, iterations and salt) given at construction, and
+ /// returns the value as a base32hex-encoded string (without
+ /// containing any white spaces). All US-ASCII letters in the
+ /// string will be lower cased.
+ ///
+ /// \param ls The absolute label sequence for which the hash value
+ /// is to be calculated.
+ /// \return Base32hex-encoded string of the hash value.
+ virtual std::string calculate(const LabelSequence& ls) const = 0;
+
/// \brief Match given NSEC3 parameters with that of the hash.
///
/// This method compares NSEC3 parameters used for hash calculation
#include <boost/scoped_ptr.hpp>
#include <dns/nsec3hash.h>
+#include <dns/labelsequence.h>
#include <dns/rdataclass.h>
#include <util/encode/hex.h>
// Check case-insensitiveness
EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
hash.calculate(Name("EXAMPLE")));
+
+ // Repeat for the LabelSequence variant.
+
+ // A couple of normal cases from the RFC5155 example.
+ EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
+ hash.calculate(LabelSequence(Name("example"))));
+ EXPECT_EQ("35MTHGPGCU1QG68FAB165KLNSNK3DPVL",
+ hash.calculate(LabelSequence(Name("a.example"))));
+
+ // Check case-insensitiveness
+ EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
+ hash.calculate(LabelSequence(Name("EXAMPLE"))));
}
TEST_F(NSEC3HashTest, calculate) {
EXPECT_EQ("CK0POJMG874LJREF7EFN8430QVIT8BSM",
NSEC3HashPtr(NSEC3Hash::create(generic::NSEC3PARAM("1 0 0 -")))
->calculate(Name("com")));
+ EXPECT_EQ("CK0POJMG874LJREF7EFN8430QVIT8BSM",
+ NSEC3HashPtr(NSEC3Hash::create(generic::NSEC3PARAM("1 0 0 -")))
+ ->calculate(LabelSequence(Name("com"))));
// Using unusually large iterations, something larger than the 8-bit range.
// (expected hash value generated by BIND 9's dnssec-signzone)
EXPECT_EQ("COG6A52MJ96MNMV3QUCAGGCO0RHCC2Q3",
NSEC3HashPtr(NSEC3Hash::create(
generic::NSEC3PARAM("1 0 256 AABBCCDD")))
- ->calculate(Name("example.org")));
+ ->calculate(LabelSequence(Name("example.org"))));
}
// Common checks for match cases
virtual string calculate(const Name&) const {
return ("00000000000000000000000000000000");
}
+ virtual string calculate(const LabelSequence&) const {
+ return ("00000000000000000000000000000000");
+ }
virtual bool match(const generic::NSEC3PARAM&) const {
return (true);
}
// Re-check an existing case using the default creator/hash implementation
EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
test_hash->calculate(Name("example")));
+ EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
+ test_hash->calculate(LabelSequence(Name("example"))));
// Replace the creator, and confirm the hash values are faked
TestNSEC3HashCreator test_creator;
test_hash.reset(NSEC3Hash::create(generic::NSEC3PARAM("1 0 12 aabbccdd")));
EXPECT_EQ("00000000000000000000000000000000",
test_hash->calculate(Name("example")));
+ EXPECT_EQ("00000000000000000000000000000000",
+ test_hash->calculate(LabelSequence(Name("example"))));
// Same for hash from NSEC3 RDATA
test_hash.reset(NSEC3Hash::create(generic::NSEC3
("1 0 12 aabbccdd " +
string(nsec3_common))));
EXPECT_EQ("00000000000000000000000000000000",
test_hash->calculate(Name("example")));
+ EXPECT_EQ("00000000000000000000000000000000",
+ test_hash->calculate(LabelSequence(Name("example"))));
// If we set a special flag big (0x80) on creation, it will act like the
// default creator.
"1 128 12 aabbccdd")));
EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
test_hash->calculate(Name("example")));
+ EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
+ test_hash->calculate(LabelSequence(Name("example"))));
test_hash.reset(NSEC3Hash::create(generic::NSEC3
("1 128 12 aabbccdd " +
string(nsec3_common))));
EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
test_hash->calculate(Name("example")));
+ EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
+ test_hash->calculate(LabelSequence(Name("example"))));
// Reset the creator to default, and confirm that
setNSEC3HashCreator(NULL);
test_hash.reset(NSEC3Hash::create(generic::NSEC3PARAM("1 0 12 aabbccdd")));
EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
test_hash->calculate(Name("example")));
+ EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
+ test_hash->calculate(LabelSequence(Name("example"))));
}
} // end namespace