rdata_tsig_unittest.cc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. // Copyright (C) 2010-2013 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 <string>
  15. #include <exceptions/exceptions.h>
  16. #include <util/buffer.h>
  17. #include <dns/exceptions.h>
  18. #include <dns/messagerenderer.h>
  19. #include <dns/rdata.h>
  20. #include <dns/rdataclass.h>
  21. #include <dns/rrclass.h>
  22. #include <dns/rrtype.h>
  23. #include <dns/tsigerror.h>
  24. #include <gtest/gtest.h>
  25. #include <dns/tests/unittest_util.h>
  26. #include <dns/tests/rdata_unittest.h>
  27. using isc::UnitTestUtil;
  28. using namespace std;
  29. using namespace isc;
  30. using namespace isc::dns;
  31. using namespace isc::util;
  32. using namespace isc::dns::rdata;
  33. const char* const valid_text1 = "hmac-md5.sig-alg.reg.int. 1286779327 300 "
  34. "0 16020 BADKEY 0";
  35. const char* const valid_text2 = "hmac-sha256. 1286779327 300 12 "
  36. "FAKEFAKEFAKEFAKE 16020 BADSIG 0";
  37. const char* const valid_text3 = "hmac-sha1. 1286779327 300 12 "
  38. "FAKEFAKEFAKEFAKE 16020 BADTIME 6 FAKEFAKE";
  39. const char* const valid_text4 = "hmac-sha1. 1286779327 300 12 "
  40. "FAKEFAKEFAKEFAKE 16020 BADSIG 6 FAKEFAKE";
  41. const char* const valid_text5 = "hmac-sha256. 1286779327 300 12 "
  42. "FAKEFAKEFAKEFAKE 16020 2845 0"; // using numeric error code
  43. const char* const too_long_label = "012345678901234567890123456789"
  44. "0123456789012345678901234567890123";
  45. // commonly used test RDATA
  46. const any::TSIG rdata_tsig((string(valid_text1)));
  47. namespace {
  48. class Rdata_TSIG_Test : public RdataTest {
  49. protected:
  50. void checkFromText_InvalidText(const string& rdata_str) {
  51. checkFromText<any::TSIG, InvalidRdataText, InvalidRdataText>(
  52. rdata_str, rdata_tsig, true, true);
  53. }
  54. void checkFromText_BadValue(const string& rdata_str) {
  55. checkFromText<any::TSIG, BadValue, BadValue>(
  56. rdata_str, rdata_tsig, true, true);
  57. }
  58. void checkFromText_LexerError(const string& rdata_str) {
  59. checkFromText
  60. <any::TSIG, InvalidRdataText, MasterLexer::LexerError>(
  61. rdata_str, rdata_tsig, true, true);
  62. }
  63. void checkFromText_TooLongLabel(const string& rdata_str) {
  64. checkFromText<any::TSIG, TooLongLabel, TooLongLabel>(
  65. rdata_str, rdata_tsig, true, true);
  66. }
  67. void checkFromText_EmptyLabel(const string& rdata_str) {
  68. checkFromText<any::TSIG, EmptyLabel, EmptyLabel>(
  69. rdata_str, rdata_tsig, true, true);
  70. }
  71. vector<uint8_t> expect_data;
  72. };
  73. TEST_F(Rdata_TSIG_Test, fromText) {
  74. // normal case. it also tests getter methods.
  75. EXPECT_EQ(Name("hmac-md5.sig-alg.reg.int"), rdata_tsig.getAlgorithm());
  76. EXPECT_EQ(1286779327, rdata_tsig.getTimeSigned());
  77. EXPECT_EQ(300, rdata_tsig.getFudge());
  78. EXPECT_EQ(0, rdata_tsig.getMACSize());
  79. EXPECT_EQ(static_cast<void*>(NULL), rdata_tsig.getMAC());
  80. EXPECT_EQ(16020, rdata_tsig.getOriginalID());
  81. EXPECT_EQ(17, rdata_tsig.getError()); // TODO: use constant
  82. EXPECT_EQ(0, rdata_tsig.getOtherLen());
  83. EXPECT_EQ(static_cast<void*>(NULL), rdata_tsig.getOtherData());
  84. any::TSIG tsig2((string(valid_text2)));
  85. EXPECT_EQ(12, tsig2.getMACSize());
  86. EXPECT_EQ(TSIGError::BAD_SIG_CODE, tsig2.getError());
  87. any::TSIG tsig3((string(valid_text3)));
  88. EXPECT_EQ(6, tsig3.getOtherLen());
  89. // The other data is unusual, but we don't reject it.
  90. EXPECT_NO_THROW(any::TSIG(string(valid_text4)));
  91. // numeric representation of TSIG error
  92. any::TSIG tsig5((string(valid_text5)));
  93. EXPECT_EQ(2845, tsig5.getError());
  94. }
  95. TEST_F(Rdata_TSIG_Test, badText) {
  96. // too many fields
  97. EXPECT_THROW(any::TSIG("foo 0 0 0 0 BADKEY 0 0"), InvalidRdataText);
  98. // not enough fields
  99. checkFromText_LexerError("foo 0 0 0 0 BADKEY");
  100. // bad domain name
  101. checkFromText_TooLongLabel(string(too_long_label) + "0 0 0 0 BADKEY 0");
  102. checkFromText_EmptyLabel("foo..bar 0 0 0 0 BADKEY");
  103. // time is too large (2814...6 is 2^48)
  104. checkFromText_InvalidText("foo 281474976710656 0 0 0 BADKEY 0");
  105. // invalid time (negative)
  106. checkFromText_InvalidText("foo -1 0 0 0 BADKEY 0");
  107. // invalid time (not a number)
  108. checkFromText_InvalidText("foo TIME 0 0 0 BADKEY 0");
  109. // fudge is too large
  110. checkFromText_InvalidText("foo 0 65536 0 0 BADKEY 0");
  111. // invalid fudge (negative)
  112. checkFromText_LexerError("foo 0 -1 0 0 BADKEY 0");
  113. // invalid fudge (not a number)
  114. checkFromText_LexerError("foo 0 FUDGE 0 0 BADKEY 0");
  115. // MAC size is too large
  116. checkFromText_InvalidText("foo 0 0 65536 0 BADKEY 0");
  117. // invalide MAC size (negative)
  118. checkFromText_LexerError("foo 0 0 -1 0 BADKEY 0");
  119. // invalid MAC size (not a number)
  120. checkFromText_LexerError("foo 0 0 MACSIZE 0 BADKEY 0");
  121. // MAC size and MAC mismatch
  122. checkFromText_InvalidText("foo 0 0 9 FAKE 0 BADKEY 0");
  123. // MAC is bad base64
  124. checkFromText_BadValue("foo 0 0 3 FAK= 0 BADKEY 0");
  125. // Unknown error code
  126. checkFromText_InvalidText("foo 0 0 0 0 TEST 0");
  127. // Numeric error code is too large
  128. checkFromText_InvalidText("foo 0 0 0 0 65536 0");
  129. // Other len is too large
  130. checkFromText_InvalidText("foo 0 0 0 0 NOERROR 65536 FAKE");
  131. // invalid Other len
  132. checkFromText_LexerError("foo 0 0 0 0 NOERROR LEN FAKE");
  133. // Other len and data mismatch
  134. checkFromText_InvalidText("foo 0 0 0 0 NOERROR 9 FAKE");
  135. }
  136. void
  137. fromWireCommonChecks(const any::TSIG& tsig) {
  138. EXPECT_EQ(Name("hmac-sha256"), tsig.getAlgorithm());
  139. EXPECT_EQ(1286978795, tsig.getTimeSigned());
  140. EXPECT_EQ(300, tsig.getFudge());
  141. vector<uint8_t> expect_mac(32, 'x');
  142. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  143. &expect_mac[0], expect_mac.size(),
  144. tsig.getMAC(), tsig.getMACSize());
  145. EXPECT_EQ(2845, tsig.getOriginalID());
  146. EXPECT_EQ(0, tsig.getOtherLen());
  147. EXPECT_EQ(static_cast<const void*>(NULL), tsig.getOtherData());
  148. }
  149. TEST_F(Rdata_TSIG_Test, createFromWire) {
  150. RdataPtr rdata(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(),
  151. "rdata_tsig_fromWire1.wire"));
  152. fromWireCommonChecks(dynamic_cast<any::TSIG&>(*rdata));
  153. }
  154. TEST_F(Rdata_TSIG_Test, createFromWireWithOtherData) {
  155. RdataPtr rdata(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(),
  156. "rdata_tsig_fromWire2.wire"));
  157. const any::TSIG& tsig(dynamic_cast<any::TSIG&>(*rdata));
  158. EXPECT_EQ(18, tsig.getError());
  159. const uint64_t otherdata = 1286978795 + 300 + 1; // time-signed + fudge + 1
  160. expect_data.resize(6);
  161. expect_data[0] = (otherdata >> 40);
  162. expect_data[1] = ((otherdata >> 32) & 0xff);
  163. expect_data[2] = ((otherdata >> 24) & 0xff);
  164. expect_data[3] = ((otherdata >> 16) & 0xff);
  165. expect_data[4] = ((otherdata >> 8) & 0xff);
  166. expect_data[5] = (otherdata & 0xff);
  167. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  168. &expect_data[0], expect_data.size(),
  169. tsig.getOtherData(), tsig.getOtherLen());
  170. }
  171. TEST_F(Rdata_TSIG_Test, createFromWireWithoutMAC) {
  172. RdataPtr rdata(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(),
  173. "rdata_tsig_fromWire3.wire"));
  174. const any::TSIG& tsig(dynamic_cast<any::TSIG&>(*rdata));
  175. EXPECT_EQ(16, tsig.getError());
  176. EXPECT_EQ(0, tsig.getMACSize());
  177. EXPECT_EQ(static_cast<const void*>(NULL), tsig.getMAC());
  178. }
  179. TEST_F(Rdata_TSIG_Test, createFromWireWithCompression) {
  180. RdataPtr rdata(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(),
  181. "rdata_tsig_fromWire4.wire",
  182. // we need to skip the dummy name:
  183. Name("hmac-sha256").getLength()));
  184. fromWireCommonChecks(dynamic_cast<any::TSIG&>(*rdata));
  185. }
  186. TEST_F(Rdata_TSIG_Test, badFromWire) {
  187. // RDLENGTH is too short:
  188. EXPECT_THROW(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(),
  189. "rdata_tsig_fromWire5.wire"),
  190. InvalidRdataLength);
  191. // RDLENGTH is too long:
  192. EXPECT_THROW(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(),
  193. "rdata_tsig_fromWire6.wire"),
  194. InvalidRdataLength);
  195. // Algorithm name is broken:
  196. EXPECT_THROW(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(),
  197. "rdata_tsig_fromWire7.wire"),
  198. DNSMessageFORMERR);
  199. // MAC size is bogus:
  200. EXPECT_THROW(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(),
  201. "rdata_tsig_fromWire8.wire"),
  202. InvalidBufferPosition);
  203. // Other-data length is bogus:
  204. EXPECT_THROW(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(),
  205. "rdata_tsig_fromWire9.wire"),
  206. InvalidBufferPosition);
  207. }
  208. TEST_F(Rdata_TSIG_Test, copyConstruct) {
  209. const any::TSIG copy(rdata_tsig);
  210. EXPECT_EQ(0, copy.compare(rdata_tsig));
  211. // Check the copied data is valid even after the original is deleted
  212. any::TSIG* copy2 = new any::TSIG(rdata_tsig);
  213. any::TSIG copy3(*copy2);
  214. delete copy2;
  215. EXPECT_EQ(0, copy3.compare(rdata_tsig));
  216. }
  217. TEST_F(Rdata_TSIG_Test, createFromParams) {
  218. EXPECT_EQ(0, rdata_tsig.compare(any::TSIG(Name("hmac-md5.sig-alg.reg.int"),
  219. 1286779327, 300, 0, NULL, 16020,
  220. 17, 0, NULL)));
  221. const uint8_t fake_data[] = { 0x14, 0x02, 0x84, 0x14, 0x02, 0x84,
  222. 0x14, 0x02, 0x84, 0x14, 0x02, 0x84 };
  223. EXPECT_EQ(0, any::TSIG((string(valid_text2))).compare(
  224. any::TSIG(Name("hmac-sha256"), 1286779327, 300, 12,
  225. fake_data, 16020, 16, 0, NULL)));
  226. const uint8_t fake_data2[] = { 0x14, 0x02, 0x84, 0x14, 0x02, 0x84 };
  227. EXPECT_EQ(0, any::TSIG((string(valid_text3))).compare(
  228. any::TSIG(Name("hmac-sha1"), 1286779327, 300, 12,
  229. fake_data, 16020, 18, 6, fake_data2)));
  230. EXPECT_THROW(any::TSIG(Name("hmac-sha256"), 1ULL << 48, 300, 12,
  231. fake_data, 16020, 18, 6, fake_data2),
  232. isc::OutOfRange);
  233. EXPECT_THROW(any::TSIG(Name("hmac-sha256"), 0, 300, 0, fake_data, 16020,
  234. 18, 0, NULL),
  235. isc::InvalidParameter);
  236. EXPECT_THROW(any::TSIG(Name("hmac-sha256"), 0, 300, 12, NULL, 16020,
  237. 18, 0, NULL),
  238. isc::InvalidParameter);
  239. EXPECT_THROW(any::TSIG(Name("hmac-sha256"), 0, 300, 0, NULL, 16020,
  240. 18, 0, fake_data),
  241. isc::InvalidParameter);
  242. EXPECT_THROW(any::TSIG(Name("hmac-sha256"), 0, 300, 0, NULL, 16020,
  243. 18, 6, NULL),
  244. isc::InvalidParameter);
  245. }
  246. TEST_F(Rdata_TSIG_Test, createFromLexer) {
  247. EXPECT_EQ(0, rdata_tsig.compare(
  248. *test::createRdataUsingLexer(RRType::TSIG(), RRClass::ANY(),
  249. valid_text1)));
  250. // Exceptions cause NULL to be returned.
  251. EXPECT_FALSE(test::createRdataUsingLexer(RRType::TSIG(), RRClass::ANY(),
  252. "foo 0 0 0 0 BADKEY 0 0"));
  253. }
  254. TEST_F(Rdata_TSIG_Test, assignment) {
  255. any::TSIG copy((string(valid_text2)));
  256. copy = rdata_tsig;
  257. EXPECT_EQ(0, copy.compare(rdata_tsig));
  258. // Check if the copied data is valid even after the original is deleted
  259. any::TSIG* copy2 = new any::TSIG(rdata_tsig);
  260. any::TSIG copy3((string(valid_text2)));
  261. copy3 = *copy2;
  262. delete copy2;
  263. EXPECT_EQ(0, copy3.compare(rdata_tsig));
  264. // Self assignment
  265. copy = copy;
  266. EXPECT_EQ(0, copy.compare(rdata_tsig));
  267. }
  268. template <typename Output>
  269. void
  270. toWireCommonChecks(Output& output) {
  271. vector<uint8_t> expect_data;
  272. output.clear();
  273. expect_data.clear();
  274. rdata_tsig.toWire(output);
  275. // read the expected wire format data and trim the RDLEN part.
  276. UnitTestUtil::readWireData("rdata_tsig_toWire1.wire", expect_data);
  277. expect_data.erase(expect_data.begin(), expect_data.begin() + 2);
  278. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  279. &expect_data[0], expect_data.size(),
  280. output.getData(), output.getLength());
  281. expect_data.clear();
  282. output.clear();
  283. any::TSIG(string(valid_text2)).toWire(output);
  284. UnitTestUtil::readWireData("rdata_tsig_toWire2.wire", expect_data);
  285. expect_data.erase(expect_data.begin(), expect_data.begin() + 2);
  286. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  287. &expect_data[0], expect_data.size(),
  288. output.getData(), output.getLength());
  289. expect_data.clear();
  290. output.clear();
  291. any::TSIG(string(valid_text3)).toWire(output);
  292. UnitTestUtil::readWireData("rdata_tsig_toWire3.wire", expect_data);
  293. expect_data.erase(expect_data.begin(), expect_data.begin() + 2);
  294. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  295. &expect_data[0], expect_data.size(),
  296. output.getData(), output.getLength());
  297. }
  298. TEST_F(Rdata_TSIG_Test, toWireBuffer) {
  299. toWireCommonChecks<OutputBuffer>(obuffer);
  300. }
  301. TEST_F(Rdata_TSIG_Test, toWireRenderer) {
  302. toWireCommonChecks<MessageRenderer>(renderer);
  303. // check algorithm name won't compressed when it would otherwise.
  304. expect_data.clear();
  305. renderer.clear();
  306. renderer.writeName(Name("hmac-md5.sig-alg.reg.int"));
  307. renderer.writeUint16(42); // RDLEN
  308. rdata_tsig.toWire(renderer);
  309. UnitTestUtil::readWireData("rdata_tsig_toWire4.wire", expect_data);
  310. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  311. &expect_data[0], expect_data.size(),
  312. renderer.getData(), renderer.getLength());
  313. // check algorithm can be used as a compression target.
  314. expect_data.clear();
  315. renderer.clear();
  316. renderer.writeUint16(42);
  317. rdata_tsig.toWire(renderer);
  318. renderer.writeName(Name("hmac-md5.sig-alg.reg.int"));
  319. UnitTestUtil::readWireData("rdata_tsig_toWire5.wire", expect_data);
  320. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  321. &expect_data[0], expect_data.size(),
  322. renderer.getData(), renderer.getLength());
  323. }
  324. TEST_F(Rdata_TSIG_Test, toText) {
  325. EXPECT_EQ(string(valid_text1), rdata_tsig.toText());
  326. EXPECT_EQ(string(valid_text2), any::TSIG(string(valid_text2)).toText());
  327. EXPECT_EQ(string(valid_text3), any::TSIG(string(valid_text3)).toText());
  328. EXPECT_EQ(string(valid_text5), any::TSIG(string(valid_text5)).toText());
  329. }
  330. TEST_F(Rdata_TSIG_Test, compare) {
  331. // test RDATAs, sorted in the ascendent order.
  332. // "AAAA" encoded in BASE64 corresponds to 0x000000, so it should be the
  333. // smallest data of the same length.
  334. vector<any::TSIG> compare_set;
  335. compare_set.push_back(any::TSIG("a.example 0 300 0 16020 0 0"));
  336. compare_set.push_back(any::TSIG("example 0 300 0 16020 0 0"));
  337. compare_set.push_back(any::TSIG("example 1 300 0 16020 0 0"));
  338. compare_set.push_back(any::TSIG("example 1 600 0 16020 0 0"));
  339. compare_set.push_back(any::TSIG("example 1 600 3 AAAA 16020 0 0"));
  340. compare_set.push_back(any::TSIG("example 1 600 3 FAKE 16020 0 0"));
  341. compare_set.push_back(any::TSIG("example 1 600 3 FAKE 16021 0 0"));
  342. compare_set.push_back(any::TSIG("example 1 600 3 FAKE 16021 1 0"));
  343. compare_set.push_back(any::TSIG("example 1 600 3 FAKE 16021 1 3 AAAA"));
  344. compare_set.push_back(any::TSIG("example 1 600 3 FAKE 16021 1 3 FAKE"));
  345. EXPECT_EQ(0, compare_set[0].compare(
  346. any::TSIG("A.EXAMPLE 0 300 0 16020 0 0")));
  347. vector<any::TSIG>::const_iterator it;
  348. vector<any::TSIG>::const_iterator it_end = compare_set.end();
  349. for (it = compare_set.begin(); it != it_end - 1; ++it) {
  350. EXPECT_GT(0, (*it).compare(*(it + 1)));
  351. EXPECT_LT(0, (*(it + 1)).compare(*it));
  352. }
  353. // comparison attempt between incompatible RR types should be rejected
  354. EXPECT_THROW(rdata_tsig.compare(*RdataTest::rdata_nomatch), bad_cast);
  355. }
  356. }