faked_nsec3.cc 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // Copyright (C) 2011 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 "faked_nsec3.h"
  15. #include <dns/name.h>
  16. #include <testutils/dnsmessage_test.h>
  17. #include <map>
  18. #include <gtest/gtest.h>
  19. using namespace std;
  20. using namespace isc::dns;
  21. using namespace isc::testutils;
  22. namespace isc {
  23. namespace datasrc {
  24. namespace test {
  25. // Constant data definitions
  26. const char* const nsec3_common = " 300 IN NSEC3 1 1 12 aabbccdd "
  27. "2T7B4G4VSA5SMI47K61MV5BV1A22BOJR A RRSIG";
  28. const char* const nsec3_rrsig_common = " 300 IN RRSIG NSEC3 5 3 3600 "
  29. "20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE";
  30. const char* const nsec3_rrsig_common2 = " 300 IN RRSIG NSEC3 5 4 7200 "
  31. "20100410172647 20100311172647 63192 example.org. gNIVj4T8t51fEU6k"
  32. "OPpvK7HOGBFZGbalN5ZKmInyrww6UWZsUNdw07ge6/U6HfG+/s61RZ/Lis2M6yUWH"
  33. "yXbNbj/QqwqgadG5dhxTArfuR02xP600x0fWX8LXzW4yLMdKVxGbzYT+vvGz71o8g"
  34. "HSY5vYTtothcZQa4BMKhmGQEk=";
  35. const char* const apex_hash = "0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM";
  36. const char* const apex_hash_lower = "0p9mhaveqvm6t7vbl5lop2u3t2rp3tom";
  37. const char* const ns1_hash = "2T7B4G4VSA5SMI47K61MV5BV1A22BOJR";
  38. const char* const w_hash = "01UDEMVP1J2F7EG6JEBPS17VP3N8I58H";
  39. const char* const xyw_hash = "2vptu5timamqttgl4luu9kg21e0aor3s";
  40. const char* const zzz_hash = "R53BQ7CC2UVMUBFU5OCMM6PERS9TK9EN";
  41. class TestNSEC3HashCreator::TestNSEC3Hash : public NSEC3Hash {
  42. private:
  43. typedef map<Name, string> NSEC3HashMap;
  44. typedef NSEC3HashMap::value_type NSEC3HashPair;
  45. NSEC3HashMap map_;
  46. public:
  47. TestNSEC3Hash() {
  48. // Build pre-defined hash
  49. map_[Name("example.org")] = apex_hash;
  50. map_[Name("www.example.org")] = "2S9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM";
  51. map_[Name("xxx.example.org")] = "Q09MHAVEQVM6T7VBL5LOP2U3T2RP3TOM";
  52. map_[Name("yyy.example.org")] = "0A9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM";
  53. map_[Name("x.y.w.example.org")] =
  54. "2VPTU5TIMAMQTTGL4LUU9KG21E0AOR3S";
  55. map_[Name("y.w.example.org")] = "K8UDEMVP1J2F7EG6JEBPS17VP3N8I58H";
  56. map_[Name("w.example.org")] = w_hash;
  57. map_[Name("zzz.example.org")] = zzz_hash;
  58. map_[Name("smallest.example.org")] =
  59. "00000000000000000000000000000000";
  60. map_[Name("largest.example.org")] =
  61. "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU";
  62. // These are used by the findNSEC3Walk test.
  63. map_[Name("n0.example.org")] = "00000000000000000000000000000000";
  64. map_[Name("n1.example.org")] = "01UDEMVP1J2F7EG6JEBPS17VP3N8I58H";
  65. map_[Name("n2.example.org")] = "02UDEMVP1J2F7EG6JEBPS17VP3N8I58H";
  66. map_[Name("n3.example.org")] = "0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM";
  67. map_[Name("n4.example.org")] = "11111111111111111111111111111111";
  68. map_[Name("n5.example.org")] = "2T7B4G4VSA5SMI47K61MV5BV1A22BOJR";
  69. map_[Name("n6.example.org")] = "44444444444444444444444444444444";
  70. map_[Name("n7.example.org")] = "R53BQ7CC2UVMUBFU5OCMM6PERS9TK9EN";
  71. map_[Name("n8.example.org")] = "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
  72. }
  73. virtual string calculate(const Name& name) const {
  74. const NSEC3HashMap::const_iterator found = map_.find(name);
  75. if (found != map_.end()) {
  76. return (found->second);
  77. }
  78. isc_throw(isc::Unexpected, "unexpected name for NSEC3 test: "
  79. << name);
  80. }
  81. virtual bool match(const rdata::generic::NSEC3PARAM&) const {
  82. return (true);
  83. }
  84. virtual bool match(const rdata::generic::NSEC3&) const {
  85. return (true);
  86. }
  87. };
  88. NSEC3Hash* TestNSEC3HashCreator::create(const rdata::generic::NSEC3PARAM&)
  89. const
  90. {
  91. return (new TestNSEC3Hash);
  92. }
  93. NSEC3Hash* TestNSEC3HashCreator::create(const rdata::generic::NSEC3&) const {
  94. return (new TestNSEC3Hash);
  95. }
  96. NSEC3Hash* TestNSEC3HashCreator::create(uint8_t, uint16_t,
  97. const uint8_t*, size_t) const
  98. {
  99. return (new TestNSEC3Hash);
  100. }
  101. void
  102. findNSEC3Check(bool expected_matched, uint8_t expected_labels,
  103. const string& expected_closest,
  104. const string& expected_next,
  105. const ZoneFinder::FindNSEC3Result& result)
  106. {
  107. EXPECT_EQ(expected_matched, result.matched);
  108. // Convert to int so the error messages would be more readable:
  109. EXPECT_EQ(static_cast<int>(expected_labels),
  110. static_cast<int>(result.closest_labels));
  111. vector<ConstRRsetPtr> actual_rrsets;
  112. ASSERT_TRUE(result.closest_proof);
  113. actual_rrsets.push_back(result.closest_proof);
  114. rrsetsCheck(expected_closest, actual_rrsets.begin(),
  115. actual_rrsets.end());
  116. actual_rrsets.clear();
  117. if (expected_next.empty()) {
  118. EXPECT_FALSE(result.next_proof);
  119. } else {
  120. ASSERT_TRUE(result.next_proof);
  121. actual_rrsets.push_back(result.next_proof);
  122. rrsetsCheck(expected_next, actual_rrsets.begin(),
  123. actual_rrsets.end());
  124. }
  125. }
  126. void
  127. performNSEC3Test(ZoneFinder &finder, bool rrsigs_exist) {
  128. // Parameter validation: the query name must be in or below the zone
  129. EXPECT_THROW(finder.findNSEC3(Name("example.com"), false), OutOfZone);
  130. EXPECT_THROW(finder.findNSEC3(Name("org"), true), OutOfZone);
  131. const Name origin("example.org");
  132. string apex_nsec3_text = string(apex_hash) + ".example.org." +
  133. string(nsec3_common);
  134. string ns1_nsec3_text = string(ns1_hash) + ".example.org." +
  135. string(nsec3_common);
  136. string w_nsec3_text = string(w_hash) + ".example.org." +
  137. string(nsec3_common);
  138. string zzz_nsec3_text = string(zzz_hash) + ".example.org." +
  139. string(nsec3_common);
  140. if (rrsigs_exist) {
  141. apex_nsec3_text += "\n" + string(apex_hash) + ".example.org." +
  142. string(nsec3_rrsig_common2);
  143. ns1_nsec3_text += "\n" + string(ns1_hash) + ".example.org." +
  144. string(nsec3_rrsig_common2);
  145. w_nsec3_text += "\n" + string(w_hash) + ".example.org." +
  146. string(nsec3_rrsig_common2);
  147. zzz_nsec3_text += "\n" + string(zzz_hash) + ".example.org." +
  148. string(nsec3_rrsig_common2);
  149. }
  150. // Apex name. It should have a matching NSEC3.
  151. {
  152. SCOPED_TRACE("apex, non recursive mode");
  153. findNSEC3Check(true, origin.getLabelCount(), apex_nsec3_text, "",
  154. finder.findNSEC3(origin, false));
  155. }
  156. // Recursive mode doesn't change the result in this case.
  157. {
  158. SCOPED_TRACE("apex, recursive mode");
  159. findNSEC3Check(true, origin.getLabelCount(), apex_nsec3_text, "",
  160. finder.findNSEC3(origin, true));
  161. }
  162. // Non existent name (in the NSEC3 namespace -- the findNSEC3 does
  163. // not look into the normal data). Disabling recursion, a covering
  164. // NSEC3 should be returned.
  165. const Name www_name("www.example.org");
  166. {
  167. SCOPED_TRACE("non existent name, non recursive mode");
  168. findNSEC3Check(false, www_name.getLabelCount(), apex_nsec3_text, "",
  169. finder.findNSEC3(www_name, false));
  170. }
  171. // Non existent name. The closest provable encloser is the apex,
  172. // and next closer is the query name itself (which NSEC3 for ns1
  173. // covers)
  174. // H(ns1) = 2T... < H(xxx) = Q0... < H(zzz) = R5...
  175. {
  176. SCOPED_TRACE("non existent name, recursive mode");
  177. findNSEC3Check(true, origin.getLabelCount(), apex_nsec3_text,
  178. ns1_nsec3_text,
  179. finder.findNSEC3(Name("xxx.example.org"), true));
  180. }
  181. // Similar to the previous case, but next closer name is different
  182. // from the query name. The closet encloser is w.example.org, and
  183. // next closer is y.w.example.org.
  184. // H(ns1) = 2T.. < H(y.w) = K8.. < H(zzz) = R5
  185. {
  186. SCOPED_TRACE("non existent name, non qname next closer");
  187. findNSEC3Check(true, Name("w.example.org").getLabelCount(),
  188. w_nsec3_text, ns1_nsec3_text,
  189. finder.findNSEC3(Name("x.y.w.example.org"),
  190. true));
  191. }
  192. // In the rest of test we check hash comparison for wrap around cases.
  193. {
  194. SCOPED_TRACE("very small hash");
  195. const Name smallest_name("smallest.example.org");
  196. findNSEC3Check(false, smallest_name.getLabelCount(),
  197. zzz_nsec3_text, "",
  198. finder.findNSEC3(smallest_name, false));
  199. }
  200. {
  201. SCOPED_TRACE("very large hash");
  202. const Name largest_name("largest.example.org");
  203. findNSEC3Check(false, largest_name.getLabelCount(),
  204. zzz_nsec3_text, "",
  205. finder.findNSEC3(largest_name, false));
  206. }
  207. }
  208. }
  209. }
  210. }