/* */ #ifndef _D_MSE_HANDSHAKE_H_ #define _D_MSE_HANDSHAKE_H_ #include "common.h" #include "SharedHandle.h" #include "BtConstants.h" #include "SocketBuffer.h" namespace aria2 { class Option; class Logger; class SocketCore; class DHKeyExchange; class ARC4Encryptor; class ARC4Decryptor; class MSEHandshake { public: enum HANDSHAKE_TYPE { HANDSHAKE_NOT_YET = 0, HANDSHAKE_LEGACY, HANDSHAKE_ENCRYPTED }; enum CRYPTO_TYPE { CRYPTO_NONE = 0, CRYPTO_PLAIN_TEXT = 0x01, CRYPTO_ARC4 = 0x02 }; private: static const size_t PRIME_BITS = 768; static const size_t KEY_LENGTH = (PRIME_BITS+7)/8; static const size_t MAX_PAD_LENGTH = 512; static const size_t VC_LENGTH = 8; static const size_t CRYPTO_BITFIELD_LENGTH = 4; static const size_t MAX_BUFFER_LENGTH = 6*1024; int32_t _cuid; SharedHandle _socket; const Option* _option; Logger* _logger; unsigned char _rbuf[MAX_BUFFER_LENGTH]; size_t _rbufLength; SocketBuffer _socketBuffer; CRYPTO_TYPE _negotiatedCryptoType; DHKeyExchange* _dh; SharedHandle _encryptor; SharedHandle _decryptor; unsigned char _infoHash[INFO_HASH_LENGTH]; unsigned char _secret[KEY_LENGTH]; bool _initiator; unsigned char _initiatorVCMarker[VC_LENGTH]; size_t _markerIndex; uint16_t _padLength; uint16_t _iaLength; unsigned char* _ia; static const unsigned char* PRIME; static const unsigned char* GENERATOR; static const unsigned char VC[VC_LENGTH]; void encryptAndSendData(const unsigned char* data, size_t length); void createReq1Hash(unsigned char* md) const; void createReq23Hash(unsigned char* md, const unsigned char* infoHash) const; uint16_t decodeLength16(const unsigned char* buffer); uint16_t decodeLength16(const char* buffer) { return decodeLength16(reinterpret_cast(buffer)); } uint16_t verifyPadLength(const unsigned char* padlenbuf, const char* padName); void verifyVC(const unsigned char* vcbuf); void verifyReq1Hash(const unsigned char* req1buf); size_t receiveNBytes(size_t bytes); public: MSEHandshake(int32_t cuid, const SharedHandle& socket, const Option* op); ~MSEHandshake(); HANDSHAKE_TYPE identifyHandshakeType(); void initEncryptionFacility(bool initiator); bool sendPublicKey(); bool receivePublicKey(); void initCipher(const unsigned char* infoHash); bool sendInitiatorStep2(); bool findInitiatorVCMarker(); bool receiveInitiatorCryptoSelectAndPadDLength(); bool receivePad(); bool findReceiverHashMarker(); bool receiveReceiverHashAndPadCLength(); bool receiveReceiverIALength(); bool receiveReceiverIA(); bool sendReceiverStep2(); // returns plain text IA const unsigned char* getIA() const; size_t getIALength() const; const unsigned char* getInfoHash() const; CRYPTO_TYPE getNegotiatedCryptoType() const; SharedHandle getEncryptor() const; SharedHandle getDecryptor() const; const unsigned char* getBuffer() const; size_t getBufferLength() const; }; } // namespace aria2 #endif // _D_MSE_HANDSHAKE_H_