123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- // Copyright (C) 2012 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 <string>
- #include <gtest/gtest.h>
- #include <boost/scoped_ptr.hpp>
- #include <dns/nsec3hash.h>
- #include <dns/rdataclass.h>
- #include <util/encode/hex.h>
- using boost::scoped_ptr;
- using namespace std;
- using namespace isc::dns;
- using namespace isc::dns::rdata;
- using namespace isc::util;
- using namespace isc::util::encode;
- namespace {
- typedef scoped_ptr<NSEC3Hash> NSEC3HashPtr;
- // Commonly used NSEC3 suffix, defined to reduce the amount of typing
- const char* const nsec3_common = "2T7B4G4VSA5SMI47K61MV5BV1A22BOJR A RRSIG";
- class NSEC3HashTest : public ::testing::Test {
- protected:
- NSEC3HashTest() :
- test_hash(NSEC3Hash::create(generic::NSEC3PARAM("1 0 12 aabbccdd"))),
- test_hash_nsec3(NSEC3Hash::create(generic::NSEC3
- ("1 0 12 aabbccdd " +
- string(nsec3_common))))
- {
- const uint8_t salt[] = {0xaa, 0xbb, 0xcc, 0xdd};
- test_hash_args.reset(NSEC3Hash::create(1, 12, salt, sizeof(salt)));
- }
- ~NSEC3HashTest() {
- // Make sure we reset the hash creator to the default
- setNSEC3HashCreator(NULL);
- }
- // An NSEC3Hash object commonly used in tests. Parameters are borrowed
- // from the RFC5155 example. Construction of this object implicitly
- // checks a successful case of the creation.
- NSEC3HashPtr test_hash;
- // Similar to test_hash, but created from NSEC3 RR.
- NSEC3HashPtr test_hash_nsec3;
- // Similar to test_hash, but created from passed args.
- NSEC3HashPtr test_hash_args;
- };
- TEST_F(NSEC3HashTest, unknownAlgorithm) {
- EXPECT_THROW(NSEC3HashPtr(
- NSEC3Hash::create(
- generic::NSEC3PARAM("2 0 12 aabbccdd"))),
- UnknownNSEC3HashAlgorithm);
- EXPECT_THROW(NSEC3HashPtr(
- NSEC3Hash::create(
- generic::NSEC3("2 0 12 aabbccdd " +
- string(nsec3_common)))),
- UnknownNSEC3HashAlgorithm);
- const uint8_t salt[] = {0xaa, 0xbb, 0xcc, 0xdd};
- EXPECT_THROW(NSEC3HashPtr(NSEC3Hash::create(2, 12, salt, sizeof(salt))),
- UnknownNSEC3HashAlgorithm);
- }
- // Common checks for NSEC3 hash calculation
- void
- calculateCheck(NSEC3Hash& hash) {
- // A couple of normal cases from the RFC5155 example.
- EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
- hash.calculate(Name("example")));
- EXPECT_EQ("35MTHGPGCU1QG68FAB165KLNSNK3DPVL",
- hash.calculate(Name("a.example")));
- // Check case-insensitiveness
- EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
- hash.calculate(Name("EXAMPLE")));
- }
- TEST_F(NSEC3HashTest, calculate) {
- {
- SCOPED_TRACE("calculate check with NSEC3PARAM based hash");
- calculateCheck(*test_hash);
- }
- {
- SCOPED_TRACE("calculate check with NSEC3 based hash");
- calculateCheck(*test_hash_nsec3);
- }
- {
- SCOPED_TRACE("calculate check with args based hash");
- calculateCheck(*test_hash_args);
- }
- // Some boundary cases: 0-iteration and empty salt. Borrowed from the
- // .com zone data.
- EXPECT_EQ("CK0POJMG874LJREF7EFN8430QVIT8BSM",
- NSEC3HashPtr(NSEC3Hash::create(generic::NSEC3PARAM("1 0 0 -")))
- ->calculate(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")));
- }
- // Common checks for match cases
- template <typename RDATAType>
- void
- matchCheck(NSEC3Hash& hash, const string& postfix) {
- // If all parameters match, it's considered to be matched.
- EXPECT_TRUE(hash.match(RDATAType("1 0 12 aabbccdd" + postfix)));
- // Algorithm doesn't match
- EXPECT_FALSE(hash.match(RDATAType("2 0 12 aabbccdd" + postfix)));
- // Iterations doesn't match
- EXPECT_FALSE(hash.match(RDATAType("1 0 1 aabbccdd" + postfix)));
- // Salt doesn't match
- EXPECT_FALSE(hash.match(RDATAType("1 0 12 aabbccde" + postfix)));
- // Salt doesn't match: the other has an empty salt
- EXPECT_FALSE(hash.match(RDATAType("1 0 12 -" + postfix)));
- // Flags don't matter
- EXPECT_TRUE(hash.match(RDATAType("1 1 12 aabbccdd" + postfix)));
- }
- TEST_F(NSEC3HashTest, matchWithNSEC3) {
- {
- SCOPED_TRACE("match NSEC3PARAM based hash against NSEC3 parameters");
- matchCheck<generic::NSEC3>(*test_hash, " " + string(nsec3_common));
- }
- {
- SCOPED_TRACE("match NSEC3 based hash against NSEC3 parameters");
- matchCheck<generic::NSEC3>(*test_hash_nsec3,
- " " + string(nsec3_common));
- }
- }
- TEST_F(NSEC3HashTest, matchWithNSEC3PARAM) {
- {
- SCOPED_TRACE("match NSEC3PARAM based hash against NSEC3 parameters");
- matchCheck<generic::NSEC3PARAM>(*test_hash, "");
- }
- {
- SCOPED_TRACE("match NSEC3 based hash against NSEC3 parameters");
- matchCheck<generic::NSEC3PARAM>(*test_hash_nsec3, "");
- }
- }
- // A simple faked hash calculator and a dedicated creator for it.
- class TestNSEC3Hash : public NSEC3Hash {
- virtual string calculate(const Name&) const {
- return ("00000000000000000000000000000000");
- }
- virtual bool match(const generic::NSEC3PARAM&) const {
- return (true);
- }
- virtual bool match(const generic::NSEC3&) const {
- return (true);
- }
- };
- // This faked creator basically creates the faked calculator regardless of
- // the passed NSEC3PARAM or NSEC3. But if the most significant bit of flags
- // is set, it will behave like the default creator.
- class TestNSEC3HashCreator : public NSEC3HashCreator {
- public:
- virtual NSEC3Hash* create(const generic::NSEC3PARAM& param) const {
- if ((param.getFlags() & 0x80) != 0) {
- return (default_creator_.create(param));
- }
- return (new TestNSEC3Hash);
- }
- virtual NSEC3Hash* create(const generic::NSEC3& nsec3) const {
- if ((nsec3.getFlags() & 0x80) != 0) {
- return (default_creator_.create(nsec3));
- }
- return (new TestNSEC3Hash);
- }
- virtual NSEC3Hash* create(uint8_t, uint16_t,
- const uint8_t*, size_t) const {
- isc_throw(isc::Unexpected,
- "This method is not implemented here.");
- }
- private:
- DefaultNSEC3HashCreator default_creator_;
- };
- TEST_F(NSEC3HashTest, setCreator) {
- // Re-check an existing case using the default creator/hash implementation
- EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
- test_hash->calculate(Name("example")));
- // Replace the creator, and confirm the hash values are faked
- TestNSEC3HashCreator test_creator;
- setNSEC3HashCreator(&test_creator);
- // Re-create the hash object with the new creator
- test_hash.reset(NSEC3Hash::create(generic::NSEC3PARAM("1 0 12 aabbccdd")));
- EXPECT_EQ("00000000000000000000000000000000",
- test_hash->calculate(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")));
- // If we set a special flag big (0x80) on creation, it will act like the
- // default creator.
- test_hash.reset(NSEC3Hash::create(generic::NSEC3PARAM(
- "1 128 12 aabbccdd")));
- EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
- test_hash->calculate(Name("example")));
- test_hash.reset(NSEC3Hash::create(generic::NSEC3
- ("1 128 12 aabbccdd " +
- string(nsec3_common))));
- EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM",
- test_hash->calculate(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")));
- }
- } // end namespace
|