MSEHandshake.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. /* <!-- copyright */
  2. /*
  3. * aria2 - The high speed download utility
  4. *
  5. * Copyright (C) 2006 Tatsuhiro Tsujikawa
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * In addition, as a special exception, the copyright holders give
  22. * permission to link the code of portions of this program with the
  23. * OpenSSL library under certain conditions as described in each
  24. * individual source file, and distribute linked combinations
  25. * including the two.
  26. * You must obey the GNU General Public License in all respects
  27. * for all of the code used other than OpenSSL. If you modify
  28. * file(s) with this exception, you may extend this exception to your
  29. * version of the file(s), but you are not obligated to do so. If you
  30. * do not wish to do so, delete this exception statement from your
  31. * version. If you delete this exception statement from all source
  32. * files in the program, then also delete it here.
  33. */
  34. /* copyright --> */
  35. #include "MSEHandshake.h"
  36. #include <cstring>
  37. #include <cassert>
  38. #include "message.h"
  39. #include "DlAbortEx.h"
  40. #include "LogFactory.h"
  41. #include "Logger.h"
  42. #include "BtHandshakeMessage.h"
  43. #include "Socket.h"
  44. #include "a2netcompat.h"
  45. #include "DHKeyExchange.h"
  46. #include "ARC4Encryptor.h"
  47. #include "ARC4Decryptor.h"
  48. #include "MessageDigestHelper.h"
  49. #include "SimpleRandomizer.h"
  50. #include "util.h"
  51. #include "DownloadContext.h"
  52. #include "prefs.h"
  53. #include "Option.h"
  54. #include "StringFormat.h"
  55. #include "bittorrent_helper.h"
  56. namespace aria2 {
  57. const unsigned char* MSEHandshake::PRIME = reinterpret_cast<const unsigned char*>("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A36210000000000090563");
  58. const unsigned char* MSEHandshake::GENERATOR = reinterpret_cast<const unsigned char*>("2");
  59. const unsigned char MSEHandshake::VC[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  60. MSEHandshake::MSEHandshake(cuid_t cuid,
  61. const SocketHandle& socket,
  62. const Option* op):
  63. cuid_(cuid),
  64. socket_(socket),
  65. option_(op),
  66. logger_(LogFactory::getInstance()),
  67. rbufLength_(0),
  68. socketBuffer_(socket),
  69. negotiatedCryptoType_(CRYPTO_NONE),
  70. dh_(0),
  71. initiator_(true),
  72. markerIndex_(0),
  73. padLength_(0),
  74. iaLength_(0),
  75. ia_(0)
  76. {}
  77. MSEHandshake::~MSEHandshake()
  78. {
  79. delete dh_;
  80. delete [] ia_;
  81. }
  82. MSEHandshake::HANDSHAKE_TYPE MSEHandshake::identifyHandshakeType()
  83. {
  84. if(!socket_->isReadable(0)) {
  85. return HANDSHAKE_NOT_YET;
  86. }
  87. size_t r = 20-rbufLength_;
  88. socket_->readData(rbuf_+rbufLength_, r);
  89. if(r == 0 && !socket_->wantRead() && !socket_->wantWrite()) {
  90. throw DL_ABORT_EX(EX_EOF_FROM_PEER);
  91. }
  92. rbufLength_ += r;
  93. if(rbufLength_ < 20) {
  94. return HANDSHAKE_NOT_YET;
  95. }
  96. if(rbuf_[0] == BtHandshakeMessage::PSTR_LENGTH &&
  97. memcmp(BtHandshakeMessage::BT_PSTR, rbuf_+1, 19) == 0) {
  98. if(logger_->debug()) {
  99. logger_->debug("CUID#%s - This is legacy BitTorrent handshake.",
  100. util::itos(cuid_).c_str());
  101. }
  102. return HANDSHAKE_LEGACY;
  103. } else {
  104. if(logger_->debug()) {
  105. logger_->debug("CUID#%s - This may be encrypted BitTorrent handshake.",
  106. util::itos(cuid_).c_str());
  107. }
  108. return HANDSHAKE_ENCRYPTED;
  109. }
  110. }
  111. void MSEHandshake::initEncryptionFacility(bool initiator)
  112. {
  113. delete dh_;
  114. dh_ = new DHKeyExchange();
  115. dh_->init(PRIME, PRIME_BITS, GENERATOR, 160);
  116. dh_->generatePublicKey();
  117. if(logger_->debug()) {
  118. logger_->debug("CUID#%s - DH initialized.", util::itos(cuid_).c_str());
  119. }
  120. initiator_ = initiator;
  121. }
  122. bool MSEHandshake::sendPublicKey()
  123. {
  124. if(socketBuffer_.sendBufferIsEmpty()) {
  125. if(logger_->debug()) {
  126. logger_->debug("CUID#%s - Sending public key.",
  127. util::itos(cuid_).c_str());
  128. }
  129. unsigned char buffer[KEY_LENGTH+MAX_PAD_LENGTH];
  130. dh_->getPublicKey(buffer, KEY_LENGTH);
  131. size_t padLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1);
  132. dh_->generateNonce(buffer+KEY_LENGTH, padLength);
  133. socketBuffer_.pushStr(std::string(&buffer[0],
  134. &buffer[KEY_LENGTH+padLength]));
  135. }
  136. socketBuffer_.send();
  137. return socketBuffer_.sendBufferIsEmpty();
  138. }
  139. bool MSEHandshake::receivePublicKey()
  140. {
  141. size_t r = KEY_LENGTH-rbufLength_;
  142. if(r > receiveNBytes(r)) {
  143. return false;
  144. }
  145. if(logger_->debug()) {
  146. logger_->debug("CUID#%s - public key received.", util::itos(cuid_).c_str());
  147. }
  148. // TODO handle exception. in catch, resbufLength = 0;
  149. dh_->computeSecret(secret_, sizeof(secret_), rbuf_, rbufLength_);
  150. // reset rbufLength_
  151. rbufLength_ = 0;
  152. return true;
  153. }
  154. void MSEHandshake::initCipher(const unsigned char* infoHash)
  155. {
  156. memcpy(infoHash_, infoHash, INFO_HASH_LENGTH);
  157. //Initialize cipher
  158. unsigned char s[4+KEY_LENGTH+INFO_HASH_LENGTH];
  159. memcpy(s, initiator_?"keyA":"keyB", 4);
  160. memcpy(s+4, secret_, KEY_LENGTH);
  161. memcpy(s+4+KEY_LENGTH, infoHash, INFO_HASH_LENGTH);
  162. unsigned char localCipherKey[20];
  163. MessageDigestHelper::digest(localCipherKey, sizeof(localCipherKey),
  164. MessageDigestContext::SHA1,
  165. s, sizeof(s));
  166. encryptor_.reset(new ARC4Encryptor());
  167. encryptor_->init(localCipherKey, sizeof(localCipherKey));
  168. unsigned char peerCipherKey[20];
  169. memcpy(s, initiator_?"keyB":"keyA", 4);
  170. MessageDigestHelper::digest(peerCipherKey, sizeof(peerCipherKey),
  171. MessageDigestContext::SHA1,
  172. s, sizeof(s));
  173. decryptor_.reset(new ARC4Decryptor());
  174. decryptor_->init(peerCipherKey, sizeof(peerCipherKey));
  175. // discard first 1024 bytes ARC4 output.
  176. unsigned char from[1024];
  177. unsigned char to[1024];
  178. encryptor_->encrypt(to, 1024, from, 1024);
  179. decryptor_->decrypt(to, 1024, from, 1024);
  180. if(initiator_) {
  181. ARC4Encryptor enc;
  182. enc.init(peerCipherKey, sizeof(peerCipherKey));
  183. // discard first 1024 bytes ARC4 output.
  184. enc.encrypt(to, 1024, from, 1024);
  185. enc.encrypt(initiatorVCMarker_, sizeof(initiatorVCMarker_), VC, sizeof(VC));
  186. }
  187. }
  188. void MSEHandshake::encryptAndSendData(const unsigned char* data, size_t length)
  189. {
  190. unsigned char temp[4096];
  191. const unsigned char* dptr = data;
  192. size_t s;
  193. size_t r = length;
  194. while(r > 0) {
  195. s = std::min(r, sizeof(temp));
  196. encryptor_->encrypt(temp, s, dptr, s);
  197. socketBuffer_.pushStr(std::string(&temp[0], &temp[s]));
  198. dptr += s;
  199. r -= s;
  200. }
  201. }
  202. void MSEHandshake::createReq1Hash(unsigned char* md) const
  203. {
  204. unsigned char buffer[100];
  205. memcpy(buffer, "req1", 4);
  206. memcpy(buffer+4, secret_, KEY_LENGTH);
  207. MessageDigestHelper::digest(md, 20, MessageDigestContext::SHA1,
  208. buffer, 4+KEY_LENGTH);
  209. }
  210. void MSEHandshake::createReq23Hash(unsigned char* md, const unsigned char* infoHash) const
  211. {
  212. unsigned char x[24];
  213. memcpy(x, "req2", 4);
  214. memcpy(x+4, infoHash, INFO_HASH_LENGTH);
  215. unsigned char xh[20];
  216. MessageDigestHelper::digest(xh, sizeof(xh), MessageDigestContext::SHA1,
  217. x, sizeof(x));
  218. unsigned char y[4+96];
  219. memcpy(y, "req3", 4);
  220. memcpy(y+4, secret_, KEY_LENGTH);
  221. unsigned char yh[20];
  222. MessageDigestHelper::digest(yh, sizeof(yh), MessageDigestContext::SHA1,
  223. y, sizeof(y));
  224. for(size_t i = 0; i < 20; ++i) {
  225. md[i] = xh[i]^yh[i];
  226. }
  227. }
  228. uint16_t MSEHandshake::decodeLength16(const unsigned char* buffer)
  229. {
  230. uint16_t be;
  231. decryptor_->decrypt(reinterpret_cast<unsigned char*>(&be),
  232. sizeof(be),
  233. buffer, sizeof(be));
  234. return ntohs(be);
  235. }
  236. bool MSEHandshake::sendInitiatorStep2()
  237. {
  238. if(socketBuffer_.sendBufferIsEmpty()) {
  239. if(logger_->debug()) {
  240. logger_->debug("CUID#%s - Sending negotiation step2.",
  241. util::itos(cuid_).c_str());
  242. }
  243. unsigned char md[20];
  244. createReq1Hash(md);
  245. socketBuffer_.pushStr(std::string(&md[0], &md[sizeof(md)]));
  246. createReq23Hash(md, infoHash_);
  247. socketBuffer_.pushStr(std::string(&md[0], &md[sizeof(md)]));
  248. {
  249. // buffer is filled in this order:
  250. // VC(VC_LENGTH bytes),
  251. // crypto_provide(CRYPTO_BITFIELD_LENGTH bytes),
  252. // len(padC)(2bytes),
  253. // padC(len(padC)bytes <= MAX_PAD_LENGTH),
  254. // len(IA)(2bytes)
  255. unsigned char buffer[VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+MAX_PAD_LENGTH+2];
  256. // VC
  257. memcpy(buffer, VC, sizeof(VC));
  258. // crypto_provide
  259. unsigned char cryptoProvide[CRYPTO_BITFIELD_LENGTH];
  260. memset(cryptoProvide, 0, sizeof(cryptoProvide));
  261. if(option_->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) {
  262. cryptoProvide[3] = CRYPTO_PLAIN_TEXT;
  263. }
  264. cryptoProvide[3] |= CRYPTO_ARC4;
  265. memcpy(buffer+VC_LENGTH, cryptoProvide, sizeof(cryptoProvide));
  266. // len(padC)
  267. uint16_t padCLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1);
  268. {
  269. uint16_t padCLengthBE = htons(padCLength);
  270. memcpy(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH, &padCLengthBE,
  271. sizeof(padCLengthBE));
  272. }
  273. // padC
  274. memset(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2, 0, padCLength);
  275. // len(IA)
  276. // currently, IA is zero-length.
  277. uint16_t iaLength = 0;
  278. {
  279. uint16_t iaLengthBE = htons(iaLength);
  280. memcpy(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+padCLength,
  281. &iaLengthBE,sizeof(iaLengthBE));
  282. }
  283. encryptAndSendData(buffer,
  284. VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+padCLength+2);
  285. }
  286. }
  287. socketBuffer_.send();
  288. return socketBuffer_.sendBufferIsEmpty();
  289. }
  290. // This function reads exactly until the end of VC marker is reached.
  291. bool MSEHandshake::findInitiatorVCMarker()
  292. {
  293. // 616 is synchronization point of initiator
  294. size_t r = 616-KEY_LENGTH-rbufLength_;
  295. if(!socket_->isReadable(0)) {
  296. return false;
  297. }
  298. socket_->peekData(rbuf_+rbufLength_, r);
  299. if(r == 0) {
  300. if(socket_->wantRead() || socket_->wantWrite()) {
  301. return false;
  302. }
  303. throw DL_ABORT_EX(EX_EOF_FROM_PEER);
  304. }
  305. // find vc
  306. {
  307. std::string buf(&rbuf_[0], &rbuf_[rbufLength_+r]);
  308. std::string vc(&initiatorVCMarker_[0], &initiatorVCMarker_[VC_LENGTH]);
  309. if((markerIndex_ = buf.find(vc)) == std::string::npos) {
  310. if(616-KEY_LENGTH <= rbufLength_+r) {
  311. throw DL_ABORT_EX("Failed to find VC marker.");
  312. } else {
  313. socket_->readData(rbuf_+rbufLength_, r);
  314. rbufLength_ += r;
  315. return false;
  316. }
  317. }
  318. }
  319. assert(markerIndex_+VC_LENGTH-rbufLength_ <= r);
  320. size_t toRead = markerIndex_+VC_LENGTH-rbufLength_;
  321. socket_->readData(rbuf_+rbufLength_, toRead);
  322. rbufLength_ += toRead;
  323. if(logger_->debug()) {
  324. logger_->debug("CUID#%s - VC marker found at %u",
  325. util::itos(cuid_).c_str(), markerIndex_);
  326. }
  327. verifyVC(rbuf_+markerIndex_);
  328. // reset rbufLength_
  329. rbufLength_ = 0;
  330. return true;
  331. }
  332. bool MSEHandshake::receiveInitiatorCryptoSelectAndPadDLength()
  333. {
  334. size_t r = CRYPTO_BITFIELD_LENGTH+2/* PadD length*/-rbufLength_;
  335. if(r > receiveNBytes(r)) {
  336. return false;
  337. }
  338. //verifyCryptoSelect
  339. unsigned char* rbufptr = rbuf_;
  340. {
  341. unsigned char cryptoSelect[CRYPTO_BITFIELD_LENGTH];
  342. decryptor_->decrypt(cryptoSelect, sizeof(cryptoSelect),
  343. rbufptr, sizeof(cryptoSelect));
  344. if(cryptoSelect[3]&CRYPTO_PLAIN_TEXT &&
  345. option_->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) {
  346. if(logger_->debug()) {
  347. logger_->debug("CUID#%s - peer prefers plaintext.",
  348. util::itos(cuid_).c_str());
  349. }
  350. negotiatedCryptoType_ = CRYPTO_PLAIN_TEXT;
  351. }
  352. if(cryptoSelect[3]&CRYPTO_ARC4) {
  353. if(logger_->debug()) {
  354. logger_->debug("CUID#%s - peer prefers ARC4",
  355. util::itos(cuid_).c_str());
  356. }
  357. negotiatedCryptoType_ = CRYPTO_ARC4;
  358. }
  359. if(negotiatedCryptoType_ == CRYPTO_NONE) {
  360. throw DL_ABORT_EX
  361. (StringFormat("CUID#%s - No supported crypto type selected.",
  362. util::itos(cuid_).c_str()).str());
  363. }
  364. }
  365. // padD length
  366. rbufptr += CRYPTO_BITFIELD_LENGTH;
  367. padLength_ = verifyPadLength(rbufptr, "PadD");
  368. // reset rbufLength_
  369. rbufLength_ = 0;
  370. return true;
  371. }
  372. bool MSEHandshake::receivePad()
  373. {
  374. if(padLength_ == 0) {
  375. return true;
  376. }
  377. size_t r = padLength_-rbufLength_;
  378. if(r > receiveNBytes(r)) {
  379. return false;
  380. }
  381. unsigned char temp[MAX_PAD_LENGTH];
  382. decryptor_->decrypt(temp, padLength_, rbuf_, padLength_);
  383. // reset rbufLength_
  384. rbufLength_ = 0;
  385. return true;
  386. }
  387. bool MSEHandshake::findReceiverHashMarker()
  388. {
  389. // 628 is synchronization limit of receiver.
  390. size_t r = 628-KEY_LENGTH-rbufLength_;
  391. if(!socket_->isReadable(0)) {
  392. return false;
  393. }
  394. socket_->peekData(rbuf_+rbufLength_, r);
  395. if(r == 0) {
  396. if(socket_->wantRead() || socket_->wantWrite()) {
  397. return false;
  398. }
  399. throw DL_ABORT_EX(EX_EOF_FROM_PEER);
  400. }
  401. // find hash('req1', S), S is secret_.
  402. {
  403. std::string buf(&rbuf_[0], &rbuf_[rbufLength_+r]);
  404. unsigned char md[20];
  405. createReq1Hash(md);
  406. std::string req1(&md[0], &md[sizeof(md)]);
  407. if((markerIndex_ = buf.find(req1)) == std::string::npos) {
  408. if(628-KEY_LENGTH <= rbufLength_+r) {
  409. throw DL_ABORT_EX("Failed to find hash marker.");
  410. } else {
  411. socket_->readData(rbuf_+rbufLength_, r);
  412. rbufLength_ += r;
  413. return false;
  414. }
  415. }
  416. }
  417. assert(markerIndex_+20-rbufLength_ <= r);
  418. size_t toRead = markerIndex_+20-rbufLength_;
  419. socket_->readData(rbuf_+rbufLength_, toRead);
  420. rbufLength_ += toRead;
  421. if(logger_->debug()) {
  422. logger_->debug("CUID#%s - Hash marker found at %u.",
  423. util::itos(cuid_).c_str(), markerIndex_);
  424. }
  425. verifyReq1Hash(rbuf_+markerIndex_);
  426. // reset rbufLength_
  427. rbufLength_ = 0;
  428. return true;
  429. }
  430. bool MSEHandshake::receiveReceiverHashAndPadCLength
  431. (const std::vector<SharedHandle<DownloadContext> >& downloadContexts)
  432. {
  433. size_t r = 20+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2/*PadC length*/-rbufLength_;
  434. if(r > receiveNBytes(r)) {
  435. return false;
  436. }
  437. // resolve info hash
  438. // pointing to the position of HASH('req2', SKEY) xor HASH('req3', S)
  439. unsigned char* rbufptr = rbuf_;
  440. SharedHandle<DownloadContext> downloadContext;
  441. for(std::vector<SharedHandle<DownloadContext> >::const_iterator i =
  442. downloadContexts.begin(), eoi = downloadContexts.end();
  443. i != eoi; ++i) {
  444. unsigned char md[20];
  445. const unsigned char* infohash = bittorrent::getInfoHash(*i);
  446. createReq23Hash(md, infohash);
  447. if(memcmp(md, rbufptr, sizeof(md)) == 0) {
  448. if(logger_->debug()) {
  449. logger_->debug("CUID#%s - info hash found: %s",
  450. util::itos(cuid_).c_str(),
  451. util::toHex(infohash, INFO_HASH_LENGTH).c_str());
  452. }
  453. downloadContext = *i;
  454. break;
  455. }
  456. }
  457. if(downloadContext.isNull()) {
  458. throw DL_ABORT_EX("Unknown info hash.");
  459. }
  460. initCipher(bittorrent::getInfoHash(downloadContext));
  461. // decrypt VC
  462. rbufptr += 20;
  463. verifyVC(rbufptr);
  464. // decrypt crypto_provide
  465. rbufptr += VC_LENGTH;
  466. {
  467. unsigned char cryptoProvide[CRYPTO_BITFIELD_LENGTH];
  468. decryptor_->decrypt(cryptoProvide, sizeof(cryptoProvide),
  469. rbufptr, sizeof(cryptoProvide));
  470. // TODO choose the crypto type based on the preference.
  471. // For now, choose ARC4.
  472. if(cryptoProvide[3]&CRYPTO_PLAIN_TEXT &&
  473. option_->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) {
  474. if(logger_->debug()) {
  475. logger_->debug("CUID#%s - peer provides plaintext.",
  476. util::itos(cuid_).c_str());
  477. }
  478. negotiatedCryptoType_ = CRYPTO_PLAIN_TEXT;
  479. } else if(cryptoProvide[3]&CRYPTO_ARC4) {
  480. if(logger_->debug()) {
  481. logger_->debug("CUID#%s - peer provides ARC4.",
  482. util::itos(cuid_).c_str());
  483. }
  484. negotiatedCryptoType_ = CRYPTO_ARC4;
  485. }
  486. if(negotiatedCryptoType_ == CRYPTO_NONE) {
  487. throw DL_ABORT_EX
  488. (StringFormat("CUID#%s - No supported crypto type provided.",
  489. util::itos(cuid_).c_str()).str());
  490. }
  491. }
  492. // decrypt PadC length
  493. rbufptr += CRYPTO_BITFIELD_LENGTH;
  494. padLength_ = verifyPadLength(rbufptr, "PadC");
  495. // reset rbufLength_
  496. rbufLength_ = 0;
  497. return true;
  498. }
  499. bool MSEHandshake::receiveReceiverIALength()
  500. {
  501. size_t r = 2-rbufLength_;
  502. assert(r > 0);
  503. if(r > receiveNBytes(r)) {
  504. return false;
  505. }
  506. iaLength_ = decodeLength16(rbuf_);
  507. if(logger_->debug()) {
  508. logger_->debug("CUID#%s - len(IA)=%u.",
  509. util::itos(cuid_).c_str(), iaLength_);
  510. }
  511. // reset rbufLength_
  512. rbufLength_ = 0;
  513. return true;
  514. }
  515. bool MSEHandshake::receiveReceiverIA()
  516. {
  517. if(iaLength_ == 0) {
  518. return true;
  519. }
  520. size_t r = iaLength_-rbufLength_;
  521. if(r > receiveNBytes(r)) {
  522. return false;
  523. }
  524. delete [] ia_;
  525. ia_ = new unsigned char[iaLength_];
  526. decryptor_->decrypt(ia_, iaLength_, rbuf_, iaLength_);
  527. if(logger_->debug()) {
  528. logger_->debug("CUID#%s - IA received.", util::itos(cuid_).c_str());
  529. }
  530. // reset rbufLength_
  531. rbufLength_ = 0;
  532. return true;
  533. }
  534. bool MSEHandshake::sendReceiverStep2()
  535. {
  536. if(socketBuffer_.sendBufferIsEmpty()) {
  537. // buffer is filled in this order:
  538. // VC(VC_LENGTH bytes),
  539. // cryptoSelect(CRYPTO_BITFIELD_LENGTH bytes),
  540. // len(padD)(2bytes),
  541. // padD(len(padD)bytes <= MAX_PAD_LENGTH)
  542. unsigned char buffer[VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+MAX_PAD_LENGTH];
  543. // VC
  544. memcpy(buffer, VC, sizeof(VC));
  545. // crypto_select
  546. unsigned char cryptoSelect[CRYPTO_BITFIELD_LENGTH];
  547. memset(cryptoSelect, 0, sizeof(cryptoSelect));
  548. cryptoSelect[3] = negotiatedCryptoType_;
  549. memcpy(buffer+VC_LENGTH, cryptoSelect, sizeof(cryptoSelect));
  550. // len(padD)
  551. uint16_t padDLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1);
  552. {
  553. uint16_t padDLengthBE = htons(padDLength);
  554. memcpy(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH, &padDLengthBE,
  555. sizeof(padDLengthBE));
  556. }
  557. // padD, all zeroed
  558. memset(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2, 0, padDLength);
  559. encryptAndSendData(buffer, VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+padDLength);
  560. }
  561. socketBuffer_.send();
  562. return socketBuffer_.sendBufferIsEmpty();
  563. }
  564. uint16_t MSEHandshake::verifyPadLength(const unsigned char* padlenbuf, const char* padName)
  565. {
  566. if(logger_->debug()) {
  567. logger_->debug("CUID#%s - Verifying Pad length for %s",
  568. util::itos(cuid_).c_str(), padName);
  569. }
  570. uint16_t padLength = decodeLength16(padlenbuf);
  571. if(logger_->debug()) {
  572. logger_->debug("CUID#%s - len(%s)=%u",
  573. util::itos(cuid_).c_str(), padName, padLength);
  574. }
  575. if(padLength > 512) {
  576. throw DL_ABORT_EX
  577. (StringFormat("Too large %s length: %u", padName, padLength).str());
  578. }
  579. return padLength;
  580. }
  581. void MSEHandshake::verifyVC(const unsigned char* vcbuf)
  582. {
  583. if(logger_->debug()) {
  584. logger_->debug("CUID#%s - Verifying VC.", util::itos(cuid_).c_str());
  585. }
  586. unsigned char vc[VC_LENGTH];
  587. decryptor_->decrypt(vc, sizeof(vc), vcbuf, sizeof(vc));
  588. if(memcmp(VC, vc, sizeof(VC)) != 0) {
  589. throw DL_ABORT_EX
  590. (StringFormat("Invalid VC: %s", util::toHex(vc, VC_LENGTH).c_str()).str());
  591. }
  592. }
  593. void MSEHandshake::verifyReq1Hash(const unsigned char* req1buf)
  594. {
  595. if(logger_->debug()) {
  596. logger_->debug("CUID#%s - Verifying req hash.", util::itos(cuid_).c_str());
  597. }
  598. unsigned char md[20];
  599. createReq1Hash(md);
  600. if(memcmp(md, req1buf, sizeof(md)) != 0) {
  601. throw DL_ABORT_EX("Invalid req1 hash found.");
  602. }
  603. }
  604. size_t MSEHandshake::receiveNBytes(size_t bytes)
  605. {
  606. size_t r = bytes;
  607. if(r > 0) {
  608. if(!socket_->isReadable(0)) {
  609. return 0;
  610. }
  611. socket_->readData(rbuf_+rbufLength_, r);
  612. if(r == 0 && !socket_->wantRead() && !socket_->wantWrite()) {
  613. throw DL_ABORT_EX(EX_EOF_FROM_PEER);
  614. }
  615. rbufLength_ += r;
  616. }
  617. return r;
  618. }
  619. } // namespace aria2