rdata_tsig_unittest.cc 17 KB

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