nsec3param_51.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // Copyright (C) 2010 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. #include <util/buffer.h>
  15. #include <util/encode/hex.h>
  16. #include <dns/messagerenderer.h>
  17. #include <dns/rdata.h>
  18. #include <dns/rdataclass.h>
  19. #include <dns/rdata/generic/detail/nsec3param_common.h>
  20. #include <boost/lexical_cast.hpp>
  21. #include <memory>
  22. #include <string>
  23. #include <sstream>
  24. #include <vector>
  25. using namespace std;
  26. using namespace isc::util;
  27. using namespace isc::util::encode;
  28. // BEGIN_ISC_NAMESPACE
  29. // BEGIN_RDATA_NAMESPACE
  30. struct NSEC3PARAMImpl {
  31. // straightforward representation of NSEC3PARAM RDATA fields
  32. NSEC3PARAMImpl(uint8_t hashalg, uint8_t flags, uint16_t iterations,
  33. const vector<uint8_t>& salt) :
  34. hashalg_(hashalg), flags_(flags), iterations_(iterations), salt_(salt)
  35. {}
  36. const uint8_t hashalg_;
  37. const uint8_t flags_;
  38. const uint16_t iterations_;
  39. const vector<uint8_t> salt_;
  40. };
  41. /// \brief Constructor from string.
  42. ///
  43. /// The given string must represent a valid NSEC3PARAM RDATA. There
  44. /// can be extra space characters at the beginning or end of the
  45. /// text (which are simply ignored), but other extra text, including
  46. /// a new line, will make the construction fail with an exception.
  47. ///
  48. /// The Hash Algorithm, Flags and Iterations fields must be within their
  49. /// valid ranges. The Salt field may contain "-" to indicate that the
  50. /// salt is of length 0. The Salt field must not contain any whitespace.
  51. ///
  52. /// \throw InvalidRdataText if any fields are out of their valid range,
  53. /// or are incorrect.
  54. ///
  55. /// \param nsec3param_str A string containing the RDATA to be created
  56. NSEC3PARAM::NSEC3PARAM(const std::string& nsec3param_str) :
  57. impl_(NULL)
  58. {
  59. // We use auto_ptr here because if there is an exception in this
  60. // constructor, the destructor is not called and there could be a
  61. // leak of the NSEC3PARAMImpl that constructFromLexer() returns.
  62. std::auto_ptr<NSEC3PARAMImpl> impl_ptr(NULL);
  63. try {
  64. std::istringstream ss(nsec3param_str);
  65. MasterLexer lexer;
  66. lexer.pushSource(ss);
  67. impl_ptr.reset(constructFromLexer(lexer));
  68. if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
  69. isc_throw(InvalidRdataText,
  70. "Extra input text for NSEC3PARAM: " << nsec3param_str);
  71. }
  72. } catch (const MasterLexer::LexerError& ex) {
  73. isc_throw(InvalidRdataText,
  74. "Failed to construct NSEC3PARAM from '" << nsec3param_str
  75. << "': " << ex.what());
  76. }
  77. impl_ = impl_ptr.release();
  78. }
  79. /// \brief Constructor with a context of MasterLexer.
  80. ///
  81. /// The \c lexer should point to the beginning of valid textual
  82. /// representation of an NSEC3PARAM RDATA.
  83. ///
  84. /// See \c NSEC3PARAM::NSEC3PARAM(const std::string&) for description of
  85. /// the expected RDATA fields.
  86. ///
  87. /// \throw MasterLexer::LexerError General parsing error such as
  88. /// missing field.
  89. /// \throw InvalidRdataText if any fields are out of their valid range,
  90. /// or are incorrect.
  91. ///
  92. /// \param lexer A \c MasterLexer object parsing a master file for the
  93. /// RDATA to be created
  94. NSEC3PARAM::NSEC3PARAM(MasterLexer& lexer, const Name*, MasterLoader::Options,
  95. MasterLoaderCallbacks&) :
  96. impl_(NULL)
  97. {
  98. impl_ = constructFromLexer(lexer);
  99. }
  100. NSEC3PARAMImpl*
  101. NSEC3PARAM::constructFromLexer(MasterLexer& lexer) {
  102. vector<uint8_t> salt;
  103. const ParseNSEC3ParamResult params =
  104. parseNSEC3ParamFromLexer("NSEC3PARAM", lexer, salt);
  105. return (new NSEC3PARAMImpl(params.algorithm, params.flags,
  106. params.iterations, salt));
  107. }
  108. NSEC3PARAM::NSEC3PARAM(InputBuffer& buffer, size_t rdata_len) :
  109. impl_(NULL)
  110. {
  111. vector<uint8_t> salt;
  112. const ParseNSEC3ParamResult params =
  113. parseNSEC3ParamWire("NSEC3PARAM", buffer, rdata_len, salt);
  114. impl_ = new NSEC3PARAMImpl(params.algorithm, params.flags,
  115. params.iterations, salt);
  116. }
  117. NSEC3PARAM::NSEC3PARAM(const NSEC3PARAM& source) :
  118. Rdata(), impl_(new NSEC3PARAMImpl(*source.impl_))
  119. {}
  120. NSEC3PARAM&
  121. NSEC3PARAM::operator=(const NSEC3PARAM& source) {
  122. if (impl_ == source.impl_) {
  123. return (*this);
  124. }
  125. NSEC3PARAMImpl* newimpl = new NSEC3PARAMImpl(*source.impl_);
  126. delete impl_;
  127. impl_ = newimpl;
  128. return (*this);
  129. }
  130. NSEC3PARAM::~NSEC3PARAM() {
  131. delete impl_;
  132. }
  133. string
  134. NSEC3PARAM::toText() const {
  135. using boost::lexical_cast;
  136. return (lexical_cast<string>(static_cast<int>(impl_->hashalg_)) +
  137. " " + lexical_cast<string>(static_cast<int>(impl_->flags_)) +
  138. " " + lexical_cast<string>(static_cast<int>(impl_->iterations_)) +
  139. " " + (impl_->salt_.empty() ? "-" : encodeHex(impl_->salt_)));
  140. }
  141. template <typename OUTPUT_TYPE>
  142. void
  143. toWireHelper(const NSEC3PARAMImpl& impl, OUTPUT_TYPE& output) {
  144. output.writeUint8(impl.hashalg_);
  145. output.writeUint8(impl.flags_);
  146. output.writeUint16(impl.iterations_);
  147. output.writeUint8(impl.salt_.size());
  148. if (!impl.salt_.empty()) {
  149. output.writeData(&impl.salt_[0], impl.salt_.size());
  150. }
  151. }
  152. void
  153. NSEC3PARAM::toWire(OutputBuffer& buffer) const {
  154. toWireHelper(*impl_, buffer);
  155. }
  156. void
  157. NSEC3PARAM::toWire(AbstractMessageRenderer& renderer) const {
  158. toWireHelper(*impl_, renderer);
  159. }
  160. int
  161. NSEC3PARAM::compare(const Rdata& other) const {
  162. const NSEC3PARAM& other_param = dynamic_cast<const NSEC3PARAM&>(other);
  163. if (impl_->hashalg_ != other_param.impl_->hashalg_) {
  164. return (impl_->hashalg_ < other_param.impl_->hashalg_ ? -1 : 1);
  165. }
  166. if (impl_->flags_ != other_param.impl_->flags_) {
  167. return (impl_->flags_ < other_param.impl_->flags_ ? -1 : 1);
  168. }
  169. if (impl_->iterations_ != other_param.impl_->iterations_) {
  170. return (impl_->iterations_ < other_param.impl_->iterations_ ? -1 : 1);
  171. }
  172. const size_t this_len = impl_->salt_.size();
  173. const size_t other_len = other_param.impl_->salt_.size();
  174. if (this_len != other_len) {
  175. return (this_len - other_len);
  176. }
  177. const size_t cmplen = min(this_len, other_len);
  178. const int cmp = (cmplen == 0) ? 0 :
  179. memcmp(&impl_->salt_.at(0), &other_param.impl_->salt_.at(0), cmplen);
  180. if (cmp != 0) {
  181. return (cmp);
  182. } else {
  183. return (this_len - other_len);
  184. }
  185. }
  186. uint8_t
  187. NSEC3PARAM::getHashalg() const {
  188. return (impl_->hashalg_);
  189. }
  190. uint8_t
  191. NSEC3PARAM::getFlags() const {
  192. return (impl_->flags_);
  193. }
  194. uint16_t
  195. NSEC3PARAM::getIterations() const {
  196. return (impl_->iterations_);
  197. }
  198. const vector<uint8_t>&
  199. NSEC3PARAM::getSalt() const {
  200. return (impl_->salt_);
  201. }
  202. // END_RDATA_NAMESPACE
  203. // END_ISC_NAMESPACE