nsec3hash.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef __NSEC3HASH_H
  15. #define __NSEC3HASH_H 1
  16. #include <string>
  17. #include <vector>
  18. #include <stdint.h>
  19. #include <exceptions/exceptions.h>
  20. namespace isc {
  21. namespace dns {
  22. class Name;
  23. namespace rdata {
  24. namespace generic {
  25. class NSEC3;
  26. class NSEC3PARAM;
  27. }
  28. }
  29. /// \brief An exception that is thrown for when an \c NSEC3Hash object is
  30. /// constructed with an unknown hash algorithm.
  31. ///
  32. /// A specific exception class is used so that the caller can selectively
  33. /// catch this exception, e.g., while loading a zone, and handle it
  34. /// accordingly.
  35. class UnknownNSEC3HashAlgorithm : public isc::Exception {
  36. public:
  37. UnknownNSEC3HashAlgorithm(const char* file, size_t line,
  38. const char* what) :
  39. isc::Exception(file, line, what) {}
  40. };
  41. /// \brief A calculator of NSEC3 hashes.
  42. ///
  43. /// This is an abstract base class that defines a simple interface to
  44. /// calculating NSEC3 hash values as defined in RFC5155.
  45. ///
  46. /// (Derived classes of) this class is designed to be "stateless" in that it
  47. /// basically doesn't hold mutable state once constructed, and hash
  48. /// calculation solely depends on the parameters given on construction and
  49. /// input to the \c calculate() method. In that sense this could be a
  50. /// single free function rather than a class, but we decided to provide the
  51. /// functionality as a class for two reasons: NSEC3 hash calculations would
  52. /// often take place more than one time in a single query or validation
  53. /// process, so it would be more efficient if we could hold some internal
  54. /// resources used for the calculation and reuse it over multiple calls to
  55. /// \c calculate() (a concrete implementation in this library actually does
  56. /// this); Second, we may want to customize the hash calculation logic for
  57. /// testing purposes or for other future extensions. For example, we may
  58. /// want to use a fake calculator for tests that returns pre-defined hash
  59. /// values (so a slight change to the test input wouldn't affect the test
  60. /// result). Using classes from this base would make it possible more
  61. /// transparently to the application.
  62. ///
  63. /// A specific derived class instance must be created by the factory method,
  64. /// \c create().
  65. ///
  66. /// There can be several ways to extend this class in future. Those include:
  67. /// - Allow customizing the factory method so the application change the
  68. /// behavior dynamically.
  69. /// - Allow to construct the class from a tuple of parameters, that is,
  70. /// integers for algorithm, iterations and flags, and opaque salt data.
  71. /// For example, we might want to use that version for validators.
  72. /// - Allow producing hash value as binary data
  73. /// - Allow updating NSEC3 parameters of a class object so we can still reuse
  74. /// the internal resources for different sets of parameters.
  75. class NSEC3Hash {
  76. protected:
  77. /// \brief The default constructor.
  78. ///
  79. /// This is defined as protected to prevent this class from being directly
  80. /// instantiated even if the class definition is modified (accidentally
  81. /// or intentionally) to have no pure virtual methods.
  82. NSEC3Hash() {}
  83. public:
  84. /// \brief Factory method of NSECHash from NSEC3PARAM RDATA.
  85. ///
  86. /// The hash algorithm given via \c param must be known to the
  87. /// implementation. Otherwise \c UnknownNSEC3HashAlgorithm exception
  88. /// will be thrown.
  89. ///
  90. /// This method creates an \c NSEC3Hash object using \c new. The caller
  91. /// is responsible for releasing it with \c delete that is compatible to
  92. /// the one used in this library. In practice, the application would
  93. /// generally need to store the returned pointer in some form of smart
  94. /// pointer; otherwise the resulting code will be quite fragile against
  95. /// exceptions (and in this case the application doesn't have to worry
  96. /// about explicit \c delete).
  97. ///
  98. /// \throw UnknownNSEC3HashAlgorithm The specified algorithm in \c param
  99. /// is unknown.
  100. /// \throw std::bad_alloc Internal resource allocation failure.
  101. ///
  102. /// \param param NSEC3 parameters used for subsequent calculation.
  103. /// \return A pointer to a concrete derived object of \c NSEC3Hash.
  104. static NSEC3Hash* create(const rdata::generic::NSEC3PARAM& param);
  105. /// \brief Factory method of NSECHash from NSEC3 RDATA.
  106. ///
  107. /// This is similar to the other version, but extracts the parameters
  108. /// for hash calculation from an NSEC3 RDATA object.
  109. static NSEC3Hash* create(const rdata::generic::NSEC3& nsec3);
  110. /// \brief Factory method of NSECHash from args.
  111. ///
  112. /// \param algorithm the NSEC3 algorithm to use; currently only 1
  113. /// (SHA-1) is supported
  114. /// \param iterations the number of iterations
  115. /// \param salt_data the salt data as a byte array
  116. /// \param salt_data_length the length of the salt data
  117. static NSEC3Hash* create(uint8_t algorithm, uint16_t iterations,
  118. const uint8_t* salt_data, size_t salt_length);
  119. /// \brief The destructor.
  120. virtual ~NSEC3Hash() {}
  121. /// \brief Calculate the NSEC3 hash.
  122. ///
  123. /// This method calculates the NSEC3 hash value for the given \c name
  124. /// with the hash parameters (algorithm, iterations and salt) given at
  125. /// construction, and returns the value as a base32hex-encoded string
  126. /// (without containing any white spaces). All US-ASCII letters in the
  127. /// string will be upper cased.
  128. ///
  129. /// \param name The domain name for which the hash value is to be
  130. /// calculated.
  131. /// \return Base32hex-encoded string of the hash value.
  132. virtual std::string calculate(const Name& name) const = 0;
  133. /// \brief Match given NSEC3 parameters with that of the hash.
  134. ///
  135. /// This method compares NSEC3 parameters used for hash calculation
  136. /// in the object with those in the given NSEC3 RDATA, and return
  137. /// true iff they completely match. In the current implementation
  138. /// only the algorithm, iterations and salt are compared; the flags
  139. /// are ignored (as they don't affect hash calculation per RFC5155).
  140. ///
  141. /// \throw None
  142. ///
  143. /// \param nsec3 An NSEC3 RDATA object whose hash parameters are to be
  144. /// matched
  145. /// \return true If the given parameters match the local ones; false
  146. /// otherwise.
  147. virtual bool match(const rdata::generic::NSEC3& nsec3) const = 0;
  148. /// \brief Match given NSEC3PARAM parameters with that of the hash.
  149. ///
  150. /// This is similar to the other version, but extracts the parameters
  151. /// to compare from an NSEC3PARAM RDATA object.
  152. virtual bool match(const rdata::generic::NSEC3PARAM& nsec3param) const = 0;
  153. };
  154. /// \brief Factory class of NSEC3Hash.
  155. ///
  156. /// This class is an abstract base class that provides the creation interfaces
  157. /// of \c NSEC3Hash objects. By defining a specific derived class of the
  158. /// creator, normally with a different specific class of \c NSEC3Hash,
  159. /// the application can use a customized implementation of \c NSEC3Hash
  160. /// without changing the library itself. The intended primary application of
  161. /// such customization is tests (it would be convenient for a test to produce
  162. /// a faked hash value regardless of the input so it doesn't have to identify
  163. /// a specific input value to produce a particular hash). Another possibility
  164. /// would be an experimental extension for a newer hash algorithm or
  165. /// implementation.
  166. ///
  167. /// The three main methods named \c create() correspond to the static factory
  168. /// methods of \c NSEC3Hash of the same name.
  169. ///
  170. /// By default, the library uses the \c DefaultNSEC3HashCreator creator.
  171. /// The \c setNSEC3HashCreator() function can be used to replace it with a
  172. /// user defined version. For such customization purposes as implementing
  173. /// experimental new hash algorithms, the application may internally want to
  174. /// use the \c DefaultNSEC3HashCreator in general cases while creating a
  175. /// customized type of \c NSEC3Hash object for that particular hash algorithm.
  176. ///
  177. /// The creator objects are generally expected to be stateless; they will
  178. /// only encapsulate the factory logic. The \c create() methods are declared
  179. /// as const member functions for this reason. But if we see the need for
  180. /// having a customized creator that benefits from its own state in future,
  181. /// this condition can be loosened.
  182. class NSEC3HashCreator {
  183. protected:
  184. /// \brief The default constructor.
  185. ///
  186. /// Make very sure this isn't directly instantiated by making it protected
  187. /// even if this class is modified to lose all pure virtual methods.
  188. NSEC3HashCreator() {}
  189. public:
  190. /// \brief The destructor.
  191. ///
  192. /// This does nothing; defined only for allowing derived classes to
  193. /// specialize its behavior.
  194. virtual ~NSEC3HashCreator() {}
  195. /// \brief Factory method of NSECHash from NSEC3PARAM RDATA.
  196. ///
  197. /// See
  198. /// <code>NSEC3Hash::create(const rdata::generic::NSEC3PARAM& param)</code>
  199. virtual NSEC3Hash* create(const rdata::generic::NSEC3PARAM& nsec3param)
  200. const = 0;
  201. /// \brief Factory method of NSECHash from NSEC3 RDATA.
  202. ///
  203. /// See
  204. /// <code>NSEC3Hash::create(const rdata::generic::NSEC3& param)</code>
  205. virtual NSEC3Hash* create(const rdata::generic::NSEC3& nsec3)
  206. const = 0;
  207. /// \brief Factory method of NSECHash from args.
  208. ///
  209. /// See
  210. /// <code>NSEC3Hash::create(uint8_t algorithm, uint16_t iterations,
  211. /// const uint8_t* salt_data,
  212. /// size_t salt_length)</code>
  213. ///
  214. /// \param algorithm the NSEC3 algorithm to use; currently only 1
  215. /// (SHA-1) is supported
  216. /// \param iterations the number of iterations
  217. /// \param salt_data the salt data as a byte array
  218. /// \param salt_data_length the length of the salt data
  219. virtual NSEC3Hash* create(uint8_t algorithm, uint16_t iterations,
  220. const uint8_t* salt_data, size_t salt_length)
  221. const = 0;
  222. };
  223. /// \brief The default NSEC3Hash creator.
  224. ///
  225. /// This derived class implements the \c NSEC3HashCreator interfaces for
  226. /// the standard NSEC3 hash calculator as defined in RFC5155. The library
  227. /// will use this creator by default, so normal applications don't have to
  228. /// be aware of this class at all. This class is publicly visible for the
  229. /// convenience of special applications that want to customize the creator
  230. /// behavior for a particular type of parameters while preserving the default
  231. /// behavior for others.
  232. class DefaultNSEC3HashCreator : public NSEC3HashCreator {
  233. public:
  234. virtual NSEC3Hash* create(const rdata::generic::NSEC3PARAM& param) const;
  235. virtual NSEC3Hash* create(const rdata::generic::NSEC3& nsec3) const;
  236. virtual NSEC3Hash* create(uint8_t algorithm, uint16_t iterations,
  237. const uint8_t* salt_data,
  238. size_t salt_length) const;
  239. };
  240. /// \brief The registrar of \c NSEC3HashCreator.
  241. ///
  242. /// This function sets or resets the system-wide \c NSEC3HashCreator that
  243. /// is used by \c NSEC3Hash::create().
  244. ///
  245. /// If \c new_creator is non NULL, the given creator object will replace
  246. /// any existing creator. If it's NULL, the default builtin creator will be
  247. /// used again from that point.
  248. ///
  249. /// When \c new_creator is non NULL, the caller is responsible for keeping
  250. /// the referenced object valid as long as it can be used via
  251. /// \c NSEC3Hash::create().
  252. ///
  253. /// \exception None
  254. /// \param new_creator A pointer to the new creator object or NULL.
  255. void setNSEC3HashCreator(const NSEC3HashCreator* new_creator);
  256. }
  257. }
  258. #endif // __NSEC3HASH_H
  259. // Local Variables:
  260. // mode: c++
  261. // End: