MSEHandshakeTest.cc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include "MSEHandshake.h"
  2. #include <cstring>
  3. #include <cppunit/extensions/HelperMacros.h>
  4. #include "Exception.h"
  5. #include "util.h"
  6. #include "prefs.h"
  7. #include "SocketCore.h"
  8. #include "Option.h"
  9. #include "DownloadContext.h"
  10. #include "FileEntry.h"
  11. #include "array_fun.h"
  12. #include "bittorrent_helper.h"
  13. namespace aria2 {
  14. class MSEHandshakeTest : public CppUnit::TestFixture {
  15. CPPUNIT_TEST_SUITE(MSEHandshakeTest);
  16. CPPUNIT_TEST(testHandshake);
  17. CPPUNIT_TEST_SUITE_END();
  18. private:
  19. std::shared_ptr<DownloadContext> dctx_;
  20. void doHandshake(const std::shared_ptr<MSEHandshake>& initiator,
  21. const std::shared_ptr<MSEHandshake>& receiver);
  22. public:
  23. void setUp()
  24. {
  25. dctx_.reset(new DownloadContext());
  26. unsigned char infoHash[20];
  27. memset(infoHash, 0, sizeof(infoHash));
  28. {
  29. auto torrentAttrs = make_unique<TorrentAttribute>();
  30. torrentAttrs->infoHash.assign(std::begin(infoHash), std::end(infoHash));
  31. dctx_->setAttribute(CTX_ATTR_BT, std::move(torrentAttrs));
  32. }
  33. }
  34. void testHandshake();
  35. };
  36. CPPUNIT_TEST_SUITE_REGISTRATION(MSEHandshakeTest);
  37. namespace {
  38. std::pair<std::shared_ptr<SocketCore>, std::shared_ptr<SocketCore>>
  39. createSocketPair()
  40. {
  41. std::shared_ptr<SocketCore> initiatorSock(new SocketCore());
  42. SocketCore receiverServerSock;
  43. receiverServerSock.bind(0);
  44. receiverServerSock.beginListen();
  45. receiverServerSock.setBlockingMode();
  46. std::pair<std::string, uint16_t> receiverAddrInfo;
  47. receiverServerSock.getAddrInfo(receiverAddrInfo);
  48. initiatorSock->establishConnection("localhost", receiverAddrInfo.second);
  49. initiatorSock->setBlockingMode();
  50. std::shared_ptr<SocketCore> receiverSock(
  51. receiverServerSock.acceptConnection());
  52. receiverSock->setBlockingMode();
  53. return std::pair<std::shared_ptr<SocketCore>, std::shared_ptr<SocketCore>>(
  54. initiatorSock, receiverSock);
  55. }
  56. } // namespace
  57. void MSEHandshakeTest::doHandshake(
  58. const std::shared_ptr<MSEHandshake>& initiator,
  59. const std::shared_ptr<MSEHandshake>& receiver)
  60. {
  61. initiator->sendPublicKey();
  62. while (initiator->getWantWrite()) {
  63. initiator->send();
  64. }
  65. while (!receiver->receivePublicKey()) {
  66. receiver->read();
  67. }
  68. receiver->sendPublicKey();
  69. while (receiver->getWantWrite()) {
  70. receiver->send();
  71. }
  72. while (!initiator->receivePublicKey()) {
  73. initiator->read();
  74. }
  75. initiator->initCipher(bittorrent::getInfoHash(dctx_));
  76. initiator->sendInitiatorStep2();
  77. while (initiator->getWantWrite()) {
  78. initiator->send();
  79. }
  80. while (!receiver->findReceiverHashMarker()) {
  81. receiver->read();
  82. }
  83. std::vector<std::shared_ptr<DownloadContext>> contexts;
  84. contexts.push_back(dctx_);
  85. while (!receiver->receiveReceiverHashAndPadCLength(contexts)) {
  86. receiver->read();
  87. }
  88. while (!receiver->receivePad()) {
  89. receiver->read();
  90. }
  91. while (!receiver->receiveReceiverIALength()) {
  92. receiver->read();
  93. }
  94. while (!receiver->receiveReceiverIA()) {
  95. receiver->read();
  96. }
  97. receiver->sendReceiverStep2();
  98. while (receiver->getWantWrite()) {
  99. receiver->send();
  100. }
  101. while (!initiator->findInitiatorVCMarker()) {
  102. initiator->read();
  103. }
  104. while (!initiator->receiveInitiatorCryptoSelectAndPadDLength()) {
  105. initiator->read();
  106. }
  107. while (!initiator->receivePad()) {
  108. initiator->read();
  109. }
  110. }
  111. namespace {
  112. std::shared_ptr<MSEHandshake>
  113. createMSEHandshake(std::shared_ptr<SocketCore> socket, bool initiator,
  114. const Option* option)
  115. {
  116. std::shared_ptr<MSEHandshake> h(new MSEHandshake(1, socket, option));
  117. h->initEncryptionFacility(initiator);
  118. return h;
  119. }
  120. } // namespace
  121. void MSEHandshakeTest::testHandshake()
  122. {
  123. {
  124. Option op;
  125. op.put(PREF_BT_MIN_CRYPTO_LEVEL, V_PLAIN);
  126. std::pair<std::shared_ptr<SocketCore>, std::shared_ptr<SocketCore>>
  127. sockPair = createSocketPair();
  128. std::shared_ptr<MSEHandshake> initiator =
  129. createMSEHandshake(sockPair.first, true, &op);
  130. std::shared_ptr<MSEHandshake> receiver =
  131. createMSEHandshake(sockPair.second, false, &op);
  132. doHandshake(initiator, receiver);
  133. CPPUNIT_ASSERT_EQUAL(MSEHandshake::CRYPTO_PLAIN_TEXT,
  134. initiator->getNegotiatedCryptoType());
  135. CPPUNIT_ASSERT_EQUAL(MSEHandshake::CRYPTO_PLAIN_TEXT,
  136. receiver->getNegotiatedCryptoType());
  137. }
  138. {
  139. Option op;
  140. op.put(PREF_BT_MIN_CRYPTO_LEVEL, V_ARC4);
  141. std::pair<std::shared_ptr<SocketCore>, std::shared_ptr<SocketCore>>
  142. sockPair = createSocketPair();
  143. std::shared_ptr<MSEHandshake> initiator =
  144. createMSEHandshake(sockPair.first, true, &op);
  145. std::shared_ptr<MSEHandshake> receiver =
  146. createMSEHandshake(sockPair.second, false, &op);
  147. doHandshake(initiator, receiver);
  148. CPPUNIT_ASSERT_EQUAL(MSEHandshake::CRYPTO_ARC4,
  149. initiator->getNegotiatedCryptoType());
  150. CPPUNIT_ASSERT_EQUAL(MSEHandshake::CRYPTO_ARC4,
  151. receiver->getNegotiatedCryptoType());
  152. }
  153. }
  154. } // namespace aria2