From: Mukund Sivaraman Date: Fri, 21 Sep 2012 06:41:31 +0000 (+0530) Subject: [2218] Move NSEC3 hash calculation to NSEC3Hash class X-Git-Tag: trac2351_base~37^2~1^2~3^2~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d26a99607b8d1e1b861de188c321e869ebb92cd1;p=thirdparty%2Fkea.git [2218] Move NSEC3 hash calculation to NSEC3Hash class --- diff --git a/src/lib/datasrc/memory/zone_finder.cc b/src/lib/datasrc/memory/zone_finder.cc index 355f8b5d92..222976de37 100644 --- a/src/lib/datasrc/memory/zone_finder.cc +++ b/src/lib/datasrc/memory/zone_finder.cc @@ -23,18 +23,11 @@ #include #include -#include -#include -#include - #include using namespace isc::dns; using namespace isc::datasrc::memory; using namespace isc::datasrc; -using namespace isc::util; -using namespace isc::util::encode; -using namespace isc::util::hash; namespace isc { namespace datasrc { @@ -453,44 +446,6 @@ FindNodeResult findNode(const ZoneData& zone_data, } // end anonymous namespace -inline void -iterateSHA1(SHA1Context* ctx, const uint8_t* input, size_t inlength, - const uint8_t* salt, size_t saltlen, - uint8_t output[SHA1_HASHSIZE]) -{ - SHA1Reset(ctx); - SHA1Input(ctx, input, inlength); - SHA1Input(ctx, salt, saltlen); // this works whether saltlen == or > 0 - SHA1Result(ctx, output); -} - -std::string -InMemoryZoneFinderNSEC3Calculate(const Name& name, - const uint16_t iterations, - const uint8_t* salt, - size_t salt_len) { - // We first need to normalize the name by converting all upper case - // characters in the labels to lower ones. - OutputBuffer obuf(Name::MAX_WIRE); - Name name_copy(name); - name_copy.downcase(); - name_copy.toWire(obuf); - - const uint8_t* const salt_buf = (salt_len > 0) ? salt : NULL; - std::vector digest(SHA1_HASHSIZE); - uint8_t* const digest_buf = &digest[0]; - - SHA1Context sha1_ctx; - iterateSHA1(&sha1_ctx, static_cast(obuf.getData()), - obuf.getLength(), salt_buf, salt_len, digest_buf); - for (unsigned int n = 0; n < iterations; ++n) { - iterateSHA1(&sha1_ctx, digest_buf, SHA1_HASHSIZE, - salt_buf, salt_len, - digest_buf); - } - - return (encodeBase32Hex(digest)); -} // Specialization of the ZoneFinder::Context for the in-memory finder. class InMemoryZoneFinder::Context : public ZoneFinder::Context { diff --git a/src/lib/datasrc/memory/zone_finder.h b/src/lib/datasrc/memory/zone_finder.h index a42f6f88bf..8cad679b88 100644 --- a/src/lib/datasrc/memory/zone_finder.h +++ b/src/lib/datasrc/memory/zone_finder.h @@ -22,6 +22,7 @@ #include #include #include +#include namespace isc { namespace datasrc { @@ -73,7 +74,7 @@ public: const isc::dns::RRClass& rrclass) : zone_data_(zone_data), rrclass_(rrclass), - nsec3_calculate_(InMemoryZoneFinderNSEC3Calculate) + nsec3_calculate_(isc::dns::NSEC3Hash::calculate) {} /// \brief Find an RRset in the datasource diff --git a/src/lib/dns/nsec3hash.cc b/src/lib/dns/nsec3hash.cc index 159dff3fb7..f19fd7dcab 100644 --- a/src/lib/dns/nsec3hash.cc +++ b/src/lib/dns/nsec3hash.cc @@ -40,6 +40,17 @@ using namespace isc::dns::rdata; namespace { +inline void +iterateSHA1(SHA1Context* ctx, const uint8_t* input, size_t inlength, + const uint8_t* salt, size_t saltlen, + uint8_t output[SHA1_HASHSIZE]) +{ + SHA1Reset(ctx); + SHA1Input(ctx, input, inlength); + SHA1Input(ctx, salt, saltlen); // this works whether saltlen == or > 0 + SHA1Result(ctx, output); +} + /// \brief A derived class of \c NSEC3Hash that implements the standard hash /// calculation specified in RFC5155. /// @@ -59,13 +70,12 @@ public: NSEC3HashRFC5155(uint8_t algorithm, uint16_t iterations, const vector& salt) : algorithm_(algorithm), iterations_(iterations), - salt_(salt), digest_(SHA1_HASHSIZE), obuf_(Name::MAX_WIRE) + salt_(salt) { if (algorithm_ != NSEC3_HASH_SHA1) { isc_throw(UnknownNSEC3HashAlgorithm, "Unknown NSEC3 algorithm: " << static_cast(algorithm_)); } - SHA1Reset(&sha1_ctx_); } virtual std::string calculate(const Name& name) const; @@ -79,47 +89,11 @@ private: const uint8_t algorithm_; const uint16_t iterations_; const vector salt_; - - // The following members are placeholder of work place and don't hold - // any state over multiple calls so can be mutable without breaking - // constness. - mutable SHA1Context sha1_ctx_; - mutable vector digest_; - mutable OutputBuffer obuf_; }; -inline void -iterateSHA1(SHA1Context* ctx, const uint8_t* input, size_t inlength, - const uint8_t* salt, size_t saltlen, - uint8_t output[SHA1_HASHSIZE]) -{ - SHA1Reset(ctx); - SHA1Input(ctx, input, inlength); - SHA1Input(ctx, salt, saltlen); // this works whether saltlen == or > 0 - SHA1Result(ctx, output); -} - string NSEC3HashRFC5155::calculate(const Name& name) const { - // We first need to normalize the name by converting all upper case - // characters in the labels to lower ones. - obuf_.clear(); - Name name_copy(name); - name_copy.downcase(); - name_copy.toWire(obuf_); - - const uint8_t saltlen = salt_.size(); - const uint8_t* const salt = (saltlen > 0) ? &salt_[0] : NULL; - uint8_t* const digest = &digest_[0]; - assert(digest_.size() == SHA1_HASHSIZE); - - iterateSHA1(&sha1_ctx_, static_cast(obuf_.getData()), - obuf_.getLength(), salt, saltlen, digest); - for (unsigned int n = 0; n < iterations_; ++n) { - iterateSHA1(&sha1_ctx_, digest, SHA1_HASHSIZE, salt, saltlen, digest); - } - - return (encodeBase32Hex(digest_)); + return (NSEC3Hash::calculate(name, iterations_, &salt_[0], salt_.size())); } bool @@ -191,5 +165,33 @@ setNSEC3HashCreator(const NSEC3HashCreator* new_creator) { creator = new_creator; } +std::string +NSEC3Hash::calculate(const Name& name, + const uint16_t iterations, + const uint8_t* salt, + size_t salt_len) { + // We first need to normalize the name by converting all upper case + // characters in the labels to lower ones. + OutputBuffer obuf(Name::MAX_WIRE); + Name name_copy(name); + name_copy.downcase(); + name_copy.toWire(obuf); + + const uint8_t* const salt_buf = (salt_len > 0) ? salt : NULL; + std::vector digest(SHA1_HASHSIZE); + uint8_t* const digest_buf = &digest[0]; + + SHA1Context sha1_ctx; + iterateSHA1(&sha1_ctx, static_cast(obuf.getData()), + obuf.getLength(), salt_buf, salt_len, digest_buf); + for (unsigned int n = 0; n < iterations; ++n) { + iterateSHA1(&sha1_ctx, digest_buf, SHA1_HASHSIZE, + salt_buf, salt_len, + digest_buf); + } + + return (encodeBase32Hex(digest)); +} + } // namespace dns } // namespace isc diff --git a/src/lib/dns/nsec3hash.h b/src/lib/dns/nsec3hash.h index 20567086c9..35b7b30054 100644 --- a/src/lib/dns/nsec3hash.h +++ b/src/lib/dns/nsec3hash.h @@ -16,7 +16,7 @@ #define __NSEC3HASH_H 1 #include - +#include #include namespace isc { @@ -131,6 +131,15 @@ public: /// \return Base32hex-encoded string of the hash value. virtual std::string calculate(const Name& name) const = 0; + /// \brief Calculate the NSEC3 SHA-1 hash. + /// + /// This method calculates the NSEC3 hash value for the given + /// \c name and hash parameters. It assumes the SHA-1 algorithm. + static std::string calculate(const Name& name, + const uint16_t iterations, + const uint8_t* salt, + size_t salt_len); + /// \brief Match given NSEC3 parameters with that of the hash. /// /// This method compares NSEC3 parameters used for hash calculation