| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647 |
- /* <!-- copyright */
- /*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
- /* copyright --> */
- #include "MSEHandshake.h"
- #include <cstring>
- #include <cassert>
- #include "message.h"
- #include "DlAbortEx.h"
- #include "LogFactory.h"
- #include "Logger.h"
- #include "BtHandshakeMessage.h"
- #include "Socket.h"
- #include "a2netcompat.h"
- #include "DHKeyExchange.h"
- #include "ARC4Encryptor.h"
- #include "ARC4Decryptor.h"
- #include "MessageDigestHelper.h"
- #include "SimpleRandomizer.h"
- #include "util.h"
- #include "DownloadContext.h"
- #include "prefs.h"
- #include "Option.h"
- #include "StringFormat.h"
- #include "bittorrent_helper.h"
- namespace aria2 {
- const unsigned char* MSEHandshake::PRIME = reinterpret_cast<const unsigned char*>("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A36210000000000090563");
- const unsigned char* MSEHandshake::GENERATOR = reinterpret_cast<const unsigned char*>("2");
- const unsigned char MSEHandshake::VC[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- MSEHandshake::MSEHandshake(int32_t cuid,
- const SocketHandle& socket,
- const Option* op):
- _cuid(cuid),
- _socket(socket),
- _option(op),
- _logger(LogFactory::getInstance()),
- _rbufLength(0),
- _socketBuffer(socket),
- _negotiatedCryptoType(CRYPTO_NONE),
- _dh(0),
- _initiator(true),
- _markerIndex(0),
- _padLength(0),
- _iaLength(0),
- _ia(0)
- {}
- MSEHandshake::~MSEHandshake()
- {
- delete _dh;
- delete [] _ia;
- }
- MSEHandshake::HANDSHAKE_TYPE MSEHandshake::identifyHandshakeType()
- {
- if(!_socket->isReadable(0)) {
- return HANDSHAKE_NOT_YET;
- }
- size_t r = 20-_rbufLength;
- _socket->readData(_rbuf+_rbufLength, r);
- if(r == 0 && !_socket->wantRead() && !_socket->wantWrite()) {
- throw DL_ABORT_EX(EX_EOF_FROM_PEER);
- }
- _rbufLength += r;
- if(_rbufLength < 20) {
- return HANDSHAKE_NOT_YET;
- }
- if(_rbuf[0] == BtHandshakeMessage::PSTR_LENGTH &&
- memcmp(BtHandshakeMessage::BT_PSTR, _rbuf+1, 19) == 0) {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - This is legacy BitTorrent handshake.", _cuid);
- }
- return HANDSHAKE_LEGACY;
- } else {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - This may be encrypted BitTorrent handshake.",
- _cuid);
- }
- return HANDSHAKE_ENCRYPTED;
- }
- }
- void MSEHandshake::initEncryptionFacility(bool initiator)
- {
- delete _dh;
- _dh = new DHKeyExchange();
- _dh->init(PRIME, PRIME_BITS, GENERATOR, 160);
- _dh->generatePublicKey();
- if(_logger->debug()) {
- _logger->debug("CUID#%d - DH initialized.", _cuid);
- }
- _initiator = initiator;
- }
- bool MSEHandshake::sendPublicKey()
- {
- if(_socketBuffer.sendBufferIsEmpty()) {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - Sending public key.", _cuid);
- }
- unsigned char buffer[KEY_LENGTH+MAX_PAD_LENGTH];
- _dh->getPublicKey(buffer, KEY_LENGTH);
- size_t padLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1);
- _dh->generateNonce(buffer+KEY_LENGTH, padLength);
- _socketBuffer.pushStr(std::string(&buffer[0],
- &buffer[KEY_LENGTH+padLength]));
- }
- _socketBuffer.send();
- return _socketBuffer.sendBufferIsEmpty();
- }
- bool MSEHandshake::receivePublicKey()
- {
- size_t r = KEY_LENGTH-_rbufLength;
- if(r > receiveNBytes(r)) {
- return false;
- }
- if(_logger->debug()) {
- _logger->debug("CUID#%d - public key received.", _cuid);
- }
- // TODO handle exception. in catch, resbufLength = 0;
- _dh->computeSecret(_secret, sizeof(_secret), _rbuf, _rbufLength);
- // reset _rbufLength
- _rbufLength = 0;
- return true;
- }
- void MSEHandshake::initCipher(const unsigned char* infoHash)
- {
- memcpy(_infoHash, infoHash, INFO_HASH_LENGTH);
- //Initialize cipher
- unsigned char s[4+KEY_LENGTH+INFO_HASH_LENGTH];
- memcpy(s, _initiator?"keyA":"keyB", 4);
- memcpy(s+4, _secret, KEY_LENGTH);
- memcpy(s+4+KEY_LENGTH, infoHash, INFO_HASH_LENGTH);
-
- unsigned char localCipherKey[20];
- MessageDigestHelper::digest(localCipherKey, sizeof(localCipherKey),
- MessageDigestContext::SHA1,
- s, sizeof(s));
- _encryptor.reset(new ARC4Encryptor());
- _encryptor->init(localCipherKey, sizeof(localCipherKey));
- unsigned char peerCipherKey[20];
- memcpy(s, _initiator?"keyB":"keyA", 4);
- MessageDigestHelper::digest(peerCipherKey, sizeof(peerCipherKey),
- MessageDigestContext::SHA1,
- s, sizeof(s));
- _decryptor.reset(new ARC4Decryptor());
- _decryptor->init(peerCipherKey, sizeof(peerCipherKey));
- // discard first 1024 bytes ARC4 output.
- unsigned char from[1024];
- unsigned char to[1024];
- _encryptor->encrypt(to, 1024, from, 1024);
- _decryptor->decrypt(to, 1024, from, 1024);
- if(_initiator) {
- ARC4Encryptor enc;
- enc.init(peerCipherKey, sizeof(peerCipherKey));
- // discard first 1024 bytes ARC4 output.
- enc.encrypt(to, 1024, from, 1024);
- enc.encrypt(_initiatorVCMarker, sizeof(_initiatorVCMarker), VC, sizeof(VC));
- }
- }
- void MSEHandshake::encryptAndSendData(const unsigned char* data, size_t length)
- {
- unsigned char temp[4096];
- const unsigned char* dptr = data;
- size_t s;
- size_t r = length;
- while(r > 0) {
- s = std::min(r, sizeof(temp));
- _encryptor->encrypt(temp, s, dptr, s);
- _socketBuffer.pushStr(std::string(&temp[0], &temp[s]));
- dptr += s;
- r -= s;
- }
- }
- void MSEHandshake::createReq1Hash(unsigned char* md) const
- {
- unsigned char buffer[100];
- memcpy(buffer, "req1", 4);
- memcpy(buffer+4, _secret, KEY_LENGTH);
- MessageDigestHelper::digest(md, 20, MessageDigestContext::SHA1,
- buffer, 4+KEY_LENGTH);
- }
- void MSEHandshake::createReq23Hash(unsigned char* md, const unsigned char* infoHash) const
- {
- unsigned char x[24];
- memcpy(x, "req2", 4);
- memcpy(x+4, infoHash, INFO_HASH_LENGTH);
- unsigned char xh[20];
- MessageDigestHelper::digest(xh, sizeof(xh), MessageDigestContext::SHA1,
- x, sizeof(x));
- unsigned char y[4+96];
- memcpy(y, "req3", 4);
- memcpy(y+4, _secret, KEY_LENGTH);
- unsigned char yh[20];
- MessageDigestHelper::digest(yh, sizeof(yh), MessageDigestContext::SHA1,
- y, sizeof(y));
-
- for(size_t i = 0; i < 20; ++i) {
- md[i] = xh[i]^yh[i];
- }
- }
- uint16_t MSEHandshake::decodeLength16(const unsigned char* buffer)
- {
- uint16_t be;
- _decryptor->decrypt(reinterpret_cast<unsigned char*>(&be),
- sizeof(be),
- buffer, sizeof(be));
- return ntohs(be);
- }
- bool MSEHandshake::sendInitiatorStep2()
- {
- if(_socketBuffer.sendBufferIsEmpty()) {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - Sending negotiation step2.", _cuid);
- }
- unsigned char md[20];
- createReq1Hash(md);
- _socketBuffer.pushStr(std::string(&md[0], &md[sizeof(md)]));
- createReq23Hash(md, _infoHash);
- _socketBuffer.pushStr(std::string(&md[0], &md[sizeof(md)]));
- {
- // buffer is filled in this order:
- // VC(VC_LENGTH bytes),
- // crypto_provide(CRYPTO_BITFIELD_LENGTH bytes),
- // len(padC)(2bytes),
- // padC(len(padC)bytes <= MAX_PAD_LENGTH),
- // len(IA)(2bytes)
- unsigned char buffer[VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+MAX_PAD_LENGTH+2];
- // VC
- memcpy(buffer, VC, sizeof(VC));
- // crypto_provide
- unsigned char cryptoProvide[CRYPTO_BITFIELD_LENGTH];
- memset(cryptoProvide, 0, sizeof(cryptoProvide));
- if(_option->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) {
- cryptoProvide[3] = CRYPTO_PLAIN_TEXT;
- }
- cryptoProvide[3] |= CRYPTO_ARC4;
- memcpy(buffer+VC_LENGTH, cryptoProvide, sizeof(cryptoProvide));
- // len(padC)
- uint16_t padCLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1);
- {
- uint16_t padCLengthBE = htons(padCLength);
- memcpy(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH, &padCLengthBE,
- sizeof(padCLengthBE));
- }
- // padC
- memset(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2, 0, padCLength);
- // len(IA)
- // currently, IA is zero-length.
- uint16_t iaLength = 0;
- {
- uint16_t iaLengthBE = htons(iaLength);
- memcpy(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+padCLength,
- &iaLengthBE,sizeof(iaLengthBE));
- }
- encryptAndSendData(buffer,
- VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+padCLength+2);
- }
- }
- _socketBuffer.send();
- return _socketBuffer.sendBufferIsEmpty();
- }
- // This function reads exactly until the end of VC marker is reached.
- bool MSEHandshake::findInitiatorVCMarker()
- {
- // 616 is synchronization point of initiator
- size_t r = 616-KEY_LENGTH-_rbufLength;
- if(!_socket->isReadable(0)) {
- return false;
- }
- _socket->peekData(_rbuf+_rbufLength, r);
- if(r == 0) {
- if(_socket->wantRead() || _socket->wantWrite()) {
- return false;
- }
- throw DL_ABORT_EX(EX_EOF_FROM_PEER);
- }
- // find vc
- {
- std::string buf(&_rbuf[0], &_rbuf[_rbufLength+r]);
- std::string vc(&_initiatorVCMarker[0], &_initiatorVCMarker[VC_LENGTH]);
- if((_markerIndex = buf.find(vc)) == std::string::npos) {
- if(616-KEY_LENGTH <= _rbufLength+r) {
- throw DL_ABORT_EX("Failed to find VC marker.");
- } else {
- _socket->readData(_rbuf+_rbufLength, r);
- _rbufLength += r;
- return false;
- }
- }
- }
- assert(_markerIndex+VC_LENGTH-_rbufLength <= r);
- size_t toRead = _markerIndex+VC_LENGTH-_rbufLength;
- _socket->readData(_rbuf+_rbufLength, toRead);
- _rbufLength += toRead;
- if(_logger->debug()) {
- _logger->debug("CUID#%d - VC marker found at %u", _cuid, _markerIndex);
- }
- verifyVC(_rbuf+_markerIndex);
- // reset _rbufLength
- _rbufLength = 0;
- return true;
- }
- bool MSEHandshake::receiveInitiatorCryptoSelectAndPadDLength()
- {
- size_t r = CRYPTO_BITFIELD_LENGTH+2/* PadD length*/-_rbufLength;
- if(r > receiveNBytes(r)) {
- return false;
- }
- //verifyCryptoSelect
- unsigned char* rbufptr = _rbuf;
- {
- unsigned char cryptoSelect[CRYPTO_BITFIELD_LENGTH];
- _decryptor->decrypt(cryptoSelect, sizeof(cryptoSelect),
- rbufptr, sizeof(cryptoSelect));
- if(cryptoSelect[3]&CRYPTO_PLAIN_TEXT &&
- _option->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - peer prefers plaintext.", _cuid);
- }
- _negotiatedCryptoType = CRYPTO_PLAIN_TEXT;
- }
- if(cryptoSelect[3]&CRYPTO_ARC4) {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - peer prefers ARC4", _cuid);
- }
- _negotiatedCryptoType = CRYPTO_ARC4;
- }
- if(_negotiatedCryptoType == CRYPTO_NONE) {
- throw DL_ABORT_EX
- (StringFormat("CUID#%d - No supported crypto type selected.", _cuid).str());
- }
- }
- // padD length
- rbufptr += CRYPTO_BITFIELD_LENGTH;
- _padLength = verifyPadLength(rbufptr, "PadD");
- // reset _rbufLength
- _rbufLength = 0;
- return true;
- }
- bool MSEHandshake::receivePad()
- {
- if(_padLength == 0) {
- return true;
- }
- size_t r = _padLength-_rbufLength;
- if(r > receiveNBytes(r)) {
- return false;
- }
- unsigned char temp[MAX_PAD_LENGTH];
- _decryptor->decrypt(temp, _padLength, _rbuf, _padLength);
- // reset _rbufLength
- _rbufLength = 0;
- return true;
- }
- bool MSEHandshake::findReceiverHashMarker()
- {
- // 628 is synchronization limit of receiver.
- size_t r = 628-KEY_LENGTH-_rbufLength;
- if(!_socket->isReadable(0)) {
- return false;
- }
- _socket->peekData(_rbuf+_rbufLength, r);
- if(r == 0) {
- if(_socket->wantRead() || _socket->wantWrite()) {
- return false;
- }
- throw DL_ABORT_EX(EX_EOF_FROM_PEER);
- }
- // find hash('req1', S), S is _secret.
- {
- std::string buf(&_rbuf[0], &_rbuf[_rbufLength+r]);
- unsigned char md[20];
- createReq1Hash(md);
- std::string req1(&md[0], &md[sizeof(md)]);
- if((_markerIndex = buf.find(req1)) == std::string::npos) {
- if(628-KEY_LENGTH <= _rbufLength+r) {
- throw DL_ABORT_EX("Failed to find hash marker.");
- } else {
- _socket->readData(_rbuf+_rbufLength, r);
- _rbufLength += r;
- return false;
- }
- }
- }
- assert(_markerIndex+20-_rbufLength <= r);
- size_t toRead = _markerIndex+20-_rbufLength;
- _socket->readData(_rbuf+_rbufLength, toRead);
- _rbufLength += toRead;
- if(_logger->debug()) {
- _logger->debug("CUID#%d - Hash marker found at %u.", _cuid, _markerIndex);
- }
- verifyReq1Hash(_rbuf+_markerIndex);
- // reset _rbufLength
- _rbufLength = 0;
- return true;
- }
- bool MSEHandshake::receiveReceiverHashAndPadCLength
- (const std::vector<SharedHandle<DownloadContext> >& downloadContexts)
- {
- size_t r = 20+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2/*PadC length*/-_rbufLength;
- if(r > receiveNBytes(r)) {
- return false;
- }
- // resolve info hash
- // pointing to the position of HASH('req2', SKEY) xor HASH('req3', S)
- unsigned char* rbufptr = _rbuf;
- SharedHandle<DownloadContext> downloadContext;
- for(std::vector<SharedHandle<DownloadContext> >::const_iterator i =
- downloadContexts.begin(), eoi = downloadContexts.end();
- i != eoi; ++i) {
- unsigned char md[20];
- const BDE& torrentAttrs = (*i)->getAttribute(bittorrent::BITTORRENT);
- createReq23Hash(md, torrentAttrs[bittorrent::INFO_HASH].uc());
- if(memcmp(md, rbufptr, sizeof(md)) == 0) {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - info hash found: %s", _cuid,
- util::toHex
- (torrentAttrs[bittorrent::INFO_HASH].s()).c_str());
- }
- downloadContext = *i;
- break;
- }
- }
- if(downloadContext.isNull()) {
- throw DL_ABORT_EX("Unknown info hash.");
- }
- initCipher(bittorrent::getInfoHash(downloadContext));
- // decrypt VC
- rbufptr += 20;
- verifyVC(rbufptr);
- // decrypt crypto_provide
- rbufptr += VC_LENGTH;
- {
- unsigned char cryptoProvide[CRYPTO_BITFIELD_LENGTH];
- _decryptor->decrypt(cryptoProvide, sizeof(cryptoProvide),
- rbufptr, sizeof(cryptoProvide));
- // TODO choose the crypto type based on the preference.
- // For now, choose ARC4.
- if(cryptoProvide[3]&CRYPTO_PLAIN_TEXT &&
- _option->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - peer provides plaintext.", _cuid);
- }
- _negotiatedCryptoType = CRYPTO_PLAIN_TEXT;
- } else if(cryptoProvide[3]&CRYPTO_ARC4) {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - peer provides ARC4.", _cuid);
- }
- _negotiatedCryptoType = CRYPTO_ARC4;
- }
- if(_negotiatedCryptoType == CRYPTO_NONE) {
- throw DL_ABORT_EX
- (StringFormat("CUID#%d - No supported crypto type provided.", _cuid).str());
- }
- }
- // decrypt PadC length
- rbufptr += CRYPTO_BITFIELD_LENGTH;
- _padLength = verifyPadLength(rbufptr, "PadC");
- // reset _rbufLength
- _rbufLength = 0;
- return true;
- }
- bool MSEHandshake::receiveReceiverIALength()
- {
- size_t r = 2-_rbufLength;
- assert(r > 0);
- if(r > receiveNBytes(r)) {
- return false;
- }
- _iaLength = decodeLength16(_rbuf);
- if(_logger->debug()) {
- _logger->debug("CUID#%d - len(IA)=%u.", _cuid, _iaLength);
- }
- // reset _rbufLength
- _rbufLength = 0;
- return true;
- }
- bool MSEHandshake::receiveReceiverIA()
- {
- if(_iaLength == 0) {
- return true;
- }
- size_t r = _iaLength-_rbufLength;
- if(r > receiveNBytes(r)) {
- return false;
- }
- delete [] _ia;
- _ia = new unsigned char[_iaLength];
- _decryptor->decrypt(_ia, _iaLength, _rbuf, _iaLength);
- if(_logger->debug()) {
- _logger->debug("CUID#%d - IA received.", _cuid);
- }
- // reset _rbufLength
- _rbufLength = 0;
- return true;
- }
- bool MSEHandshake::sendReceiverStep2()
- {
- if(_socketBuffer.sendBufferIsEmpty()) {
- // buffer is filled in this order:
- // VC(VC_LENGTH bytes),
- // cryptoSelect(CRYPTO_BITFIELD_LENGTH bytes),
- // len(padD)(2bytes),
- // padD(len(padD)bytes <= MAX_PAD_LENGTH)
- unsigned char buffer[VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+MAX_PAD_LENGTH];
- // VC
- memcpy(buffer, VC, sizeof(VC));
- // crypto_select
- unsigned char cryptoSelect[CRYPTO_BITFIELD_LENGTH];
- memset(cryptoSelect, 0, sizeof(cryptoSelect));
- cryptoSelect[3] = _negotiatedCryptoType;
- memcpy(buffer+VC_LENGTH, cryptoSelect, sizeof(cryptoSelect));
- // len(padD)
- uint16_t padDLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1);
- {
- uint16_t padDLengthBE = htons(padDLength);
- memcpy(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH, &padDLengthBE,
- sizeof(padDLengthBE));
- }
- // padD, all zeroed
- memset(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2, 0, padDLength);
- encryptAndSendData(buffer, VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+padDLength);
- }
- _socketBuffer.send();
- return _socketBuffer.sendBufferIsEmpty();
- }
- uint16_t MSEHandshake::verifyPadLength(const unsigned char* padlenbuf, const char* padName)
- {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - Verifying Pad length for %s", _cuid, padName);
- }
- uint16_t padLength = decodeLength16(padlenbuf);
- if(_logger->debug()) {
- _logger->debug("CUID#%d - len(%s)=%u", _cuid, padName, padLength);
- }
- if(padLength > 512) {
- throw DL_ABORT_EX
- (StringFormat("Too large %s length: %u", padName, padLength).str());
- }
- return padLength;
- }
- void MSEHandshake::verifyVC(const unsigned char* vcbuf)
- {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - Verifying VC.", _cuid);
- }
- unsigned char vc[VC_LENGTH];
- _decryptor->decrypt(vc, sizeof(vc), vcbuf, sizeof(vc));
- if(memcmp(VC, vc, sizeof(VC)) != 0) {
- throw DL_ABORT_EX
- (StringFormat("Invalid VC: %s", util::toHex(vc, VC_LENGTH).c_str()).str());
- }
- }
- void MSEHandshake::verifyReq1Hash(const unsigned char* req1buf)
- {
- if(_logger->debug()) {
- _logger->debug("CUID#%d - Verifying req hash.", _cuid);
- }
- unsigned char md[20];
- createReq1Hash(md);
- if(memcmp(md, req1buf, sizeof(md)) != 0) {
- throw DL_ABORT_EX("Invalid req1 hash found.");
- }
- }
- size_t MSEHandshake::receiveNBytes(size_t bytes)
- {
- size_t r = bytes;
- if(r > 0) {
- if(!_socket->isReadable(0)) {
- return 0;
- }
- _socket->readData(_rbuf+_rbufLength, r);
- if(r == 0 && !_socket->wantRead() && !_socket->wantWrite()) {
- throw DL_ABORT_EX(EX_EOF_FROM_PEER);
- }
- _rbufLength += r;
- }
- return r;
- }
- } // namespace aria2
|