MSEHandshake.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  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 BDE& torrentAttrs = (*i)->getAttribute(bittorrent::BITTORRENT);
  446. createReq23Hash(md, torrentAttrs[bittorrent::INFO_HASH].uc());
  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
  452. (torrentAttrs[bittorrent::INFO_HASH].s()).c_str());
  453. }
  454. downloadContext = *i;
  455. break;
  456. }
  457. }
  458. if(downloadContext.isNull()) {
  459. throw DL_ABORT_EX("Unknown info hash.");
  460. }
  461. initCipher(bittorrent::getInfoHash(downloadContext));
  462. // decrypt VC
  463. rbufptr += 20;
  464. verifyVC(rbufptr);
  465. // decrypt crypto_provide
  466. rbufptr += VC_LENGTH;
  467. {
  468. unsigned char cryptoProvide[CRYPTO_BITFIELD_LENGTH];
  469. _decryptor->decrypt(cryptoProvide, sizeof(cryptoProvide),
  470. rbufptr, sizeof(cryptoProvide));
  471. // TODO choose the crypto type based on the preference.
  472. // For now, choose ARC4.
  473. if(cryptoProvide[3]&CRYPTO_PLAIN_TEXT &&
  474. _option->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) {
  475. if(_logger->debug()) {
  476. _logger->debug("CUID#%s - peer provides plaintext.",
  477. util::itos(_cuid).c_str());
  478. }
  479. _negotiatedCryptoType = CRYPTO_PLAIN_TEXT;
  480. } else if(cryptoProvide[3]&CRYPTO_ARC4) {
  481. if(_logger->debug()) {
  482. _logger->debug("CUID#%s - peer provides ARC4.",
  483. util::itos(_cuid).c_str());
  484. }
  485. _negotiatedCryptoType = CRYPTO_ARC4;
  486. }
  487. if(_negotiatedCryptoType == CRYPTO_NONE) {
  488. throw DL_ABORT_EX
  489. (StringFormat("CUID#%s - No supported crypto type provided.",
  490. util::itos(_cuid).c_str()).str());
  491. }
  492. }
  493. // decrypt PadC length
  494. rbufptr += CRYPTO_BITFIELD_LENGTH;
  495. _padLength = verifyPadLength(rbufptr, "PadC");
  496. // reset _rbufLength
  497. _rbufLength = 0;
  498. return true;
  499. }
  500. bool MSEHandshake::receiveReceiverIALength()
  501. {
  502. size_t r = 2-_rbufLength;
  503. assert(r > 0);
  504. if(r > receiveNBytes(r)) {
  505. return false;
  506. }
  507. _iaLength = decodeLength16(_rbuf);
  508. if(_logger->debug()) {
  509. _logger->debug("CUID#%s - len(IA)=%u.",
  510. util::itos(_cuid).c_str(), _iaLength);
  511. }
  512. // reset _rbufLength
  513. _rbufLength = 0;
  514. return true;
  515. }
  516. bool MSEHandshake::receiveReceiverIA()
  517. {
  518. if(_iaLength == 0) {
  519. return true;
  520. }
  521. size_t r = _iaLength-_rbufLength;
  522. if(r > receiveNBytes(r)) {
  523. return false;
  524. }
  525. delete [] _ia;
  526. _ia = new unsigned char[_iaLength];
  527. _decryptor->decrypt(_ia, _iaLength, _rbuf, _iaLength);
  528. if(_logger->debug()) {
  529. _logger->debug("CUID#%s - IA received.", util::itos(_cuid).c_str());
  530. }
  531. // reset _rbufLength
  532. _rbufLength = 0;
  533. return true;
  534. }
  535. bool MSEHandshake::sendReceiverStep2()
  536. {
  537. if(_socketBuffer.sendBufferIsEmpty()) {
  538. // buffer is filled in this order:
  539. // VC(VC_LENGTH bytes),
  540. // cryptoSelect(CRYPTO_BITFIELD_LENGTH bytes),
  541. // len(padD)(2bytes),
  542. // padD(len(padD)bytes <= MAX_PAD_LENGTH)
  543. unsigned char buffer[VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+MAX_PAD_LENGTH];
  544. // VC
  545. memcpy(buffer, VC, sizeof(VC));
  546. // crypto_select
  547. unsigned char cryptoSelect[CRYPTO_BITFIELD_LENGTH];
  548. memset(cryptoSelect, 0, sizeof(cryptoSelect));
  549. cryptoSelect[3] = _negotiatedCryptoType;
  550. memcpy(buffer+VC_LENGTH, cryptoSelect, sizeof(cryptoSelect));
  551. // len(padD)
  552. uint16_t padDLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1);
  553. {
  554. uint16_t padDLengthBE = htons(padDLength);
  555. memcpy(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH, &padDLengthBE,
  556. sizeof(padDLengthBE));
  557. }
  558. // padD, all zeroed
  559. memset(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2, 0, padDLength);
  560. encryptAndSendData(buffer, VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+padDLength);
  561. }
  562. _socketBuffer.send();
  563. return _socketBuffer.sendBufferIsEmpty();
  564. }
  565. uint16_t MSEHandshake::verifyPadLength(const unsigned char* padlenbuf, const char* padName)
  566. {
  567. if(_logger->debug()) {
  568. _logger->debug("CUID#%s - Verifying Pad length for %s",
  569. util::itos(_cuid).c_str(), padName);
  570. }
  571. uint16_t padLength = decodeLength16(padlenbuf);
  572. if(_logger->debug()) {
  573. _logger->debug("CUID#%s - len(%s)=%u",
  574. util::itos(_cuid).c_str(), padName, padLength);
  575. }
  576. if(padLength > 512) {
  577. throw DL_ABORT_EX
  578. (StringFormat("Too large %s length: %u", padName, padLength).str());
  579. }
  580. return padLength;
  581. }
  582. void MSEHandshake::verifyVC(const unsigned char* vcbuf)
  583. {
  584. if(_logger->debug()) {
  585. _logger->debug("CUID#%s - Verifying VC.", util::itos(_cuid).c_str());
  586. }
  587. unsigned char vc[VC_LENGTH];
  588. _decryptor->decrypt(vc, sizeof(vc), vcbuf, sizeof(vc));
  589. if(memcmp(VC, vc, sizeof(VC)) != 0) {
  590. throw DL_ABORT_EX
  591. (StringFormat("Invalid VC: %s", util::toHex(vc, VC_LENGTH).c_str()).str());
  592. }
  593. }
  594. void MSEHandshake::verifyReq1Hash(const unsigned char* req1buf)
  595. {
  596. if(_logger->debug()) {
  597. _logger->debug("CUID#%s - Verifying req hash.", util::itos(_cuid).c_str());
  598. }
  599. unsigned char md[20];
  600. createReq1Hash(md);
  601. if(memcmp(md, req1buf, sizeof(md)) != 0) {
  602. throw DL_ABORT_EX("Invalid req1 hash found.");
  603. }
  604. }
  605. size_t MSEHandshake::receiveNBytes(size_t bytes)
  606. {
  607. size_t r = bytes;
  608. if(r > 0) {
  609. if(!_socket->isReadable(0)) {
  610. return 0;
  611. }
  612. _socket->readData(_rbuf+_rbufLength, r);
  613. if(r == 0 && !_socket->wantRead() && !_socket->wantWrite()) {
  614. throw DL_ABORT_EX(EX_EOF_FROM_PEER);
  615. }
  616. _rbufLength += r;
  617. }
  618. return r;
  619. }
  620. } // namespace aria2