sshfp_44.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. #include <config.h>
  15. #include <string>
  16. #include <boost/lexical_cast.hpp>
  17. #include <exceptions/exceptions.h>
  18. #include <util/buffer.h>
  19. #include <util/encode/hex.h>
  20. #include <dns/name.h>
  21. #include <dns/messagerenderer.h>
  22. #include <dns/rdata.h>
  23. #include <dns/rdataclass.h>
  24. using namespace std;
  25. using namespace boost;
  26. using namespace isc::util;
  27. using namespace isc::util::encode;
  28. // BEGIN_ISC_NAMESPACE
  29. // BEGIN_RDATA_NAMESPACE
  30. SSHFP::SSHFP(InputBuffer& buffer, size_t rdata_len)
  31. {
  32. if (rdata_len < 2) {
  33. isc_throw(InvalidRdataLength, "SSHFP record too short");
  34. }
  35. algorithm_ = buffer.readUint8();
  36. fingerprint_type_ = buffer.readUint8();
  37. rdata_len -= 2;
  38. fingerprint_.resize(rdata_len);
  39. buffer.readData(&fingerprint_[0], rdata_len);
  40. }
  41. SSHFP::SSHFP(const std::string& sshfp_str)
  42. {
  43. std::istringstream iss(sshfp_str);
  44. // peekc should be of iss's char_type for isspace to work
  45. std::istringstream::char_type peekc;
  46. std::stringbuf fingerprintbuf;
  47. uint32_t algorithm, fingerprint_type;
  48. iss >> algorithm >> fingerprint_type;
  49. if (iss.bad() || iss.fail()) {
  50. isc_throw(InvalidRdataText, "Invalid SSHFP text");
  51. }
  52. if ((algorithm < 1) || (algorithm > 2)) {
  53. isc_throw(InvalidRdataText, "SSHFP algorithm number out of range");
  54. }
  55. if (fingerprint_type != 1) {
  56. isc_throw(InvalidRdataText, "SSHFP fingerprint type out of range");
  57. }
  58. iss.read(&peekc, 1);
  59. if (!iss.good() || !isspace(peekc, iss.getloc())) {
  60. isc_throw(InvalidRdataText, "SSHFP presentation format error");
  61. }
  62. iss >> &fingerprintbuf;
  63. algorithm_ = algorithm;
  64. fingerprint_type_ = fingerprint_type;
  65. decodeHex(fingerprintbuf.str(), fingerprint_);
  66. }
  67. SSHFP::SSHFP(uint8_t algorithm, uint8_t fingerprint_type, const std::string& fingerprint)
  68. {
  69. if ((algorithm < 1) || (algorithm > 2)) {
  70. isc_throw(InvalidRdataText, "SSHFP algorithm number out of range");
  71. }
  72. if (fingerprint_type != 1) {
  73. isc_throw(InvalidRdataText, "SSHFP fingerprint type out of range");
  74. }
  75. algorithm_ = algorithm;
  76. fingerprint_type_ = fingerprint_type;
  77. decodeHex(fingerprint, fingerprint_);
  78. }
  79. SSHFP::SSHFP(const SSHFP& other) :
  80. Rdata(), algorithm_(other.algorithm_), fingerprint_type_(other.fingerprint_type_), fingerprint_(other.fingerprint_)
  81. {}
  82. void
  83. SSHFP::toWire(OutputBuffer& buffer) const {
  84. buffer.writeUint8(algorithm_);
  85. buffer.writeUint8(fingerprint_type_);
  86. buffer.writeData(&fingerprint_[0], fingerprint_.size());
  87. }
  88. void
  89. SSHFP::toWire(AbstractMessageRenderer& renderer) const {
  90. renderer.writeUint8(algorithm_);
  91. renderer.writeUint8(fingerprint_type_);
  92. renderer.writeData(&fingerprint_[0], fingerprint_.size());
  93. }
  94. string
  95. SSHFP::toText() const {
  96. return (lexical_cast<string>(static_cast<int>(algorithm_)) +
  97. " " + lexical_cast<string>(static_cast<int>(fingerprint_type_)) +
  98. " " + encodeHex(fingerprint_));
  99. }
  100. int
  101. SSHFP::compare(const Rdata& other) const {
  102. const SSHFP& other_sshfp = dynamic_cast<const SSHFP&>(other);
  103. /* This doesn't really make any sort of sense, but in the name of
  104. consistency... */
  105. if (algorithm_ < other_sshfp.algorithm_) {
  106. return (-1);
  107. } else if (algorithm_ > other_sshfp.algorithm_) {
  108. return (1);
  109. }
  110. if (fingerprint_type_ < other_sshfp.fingerprint_type_) {
  111. return (-1);
  112. } else if (fingerprint_type_ > other_sshfp.fingerprint_type_) {
  113. return (1);
  114. }
  115. size_t this_len = fingerprint_.size();
  116. size_t other_len = other_sshfp.fingerprint_.size();
  117. size_t cmplen = min(this_len, other_len);
  118. int cmp = memcmp(&fingerprint_[0], &other_sshfp.fingerprint_[0], cmplen);
  119. if (cmp != 0) {
  120. return (cmp);
  121. } else {
  122. return ((this_len == other_len)
  123. ? 0 : (this_len < other_len) ? -1 : 1);
  124. }
  125. }
  126. uint8_t
  127. SSHFP::getSSHFPAlgorithmNumber() const {
  128. return (algorithm_);
  129. }
  130. uint8_t
  131. SSHFP::getSSHFPFingerprintType() const {
  132. return (fingerprint_type_);
  133. }
  134. // END_RDATA_NAMESPACE
  135. // END_ISC_NAMESPACE