1// 2// This file is part of the aMule Project. 3// 4// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 5// Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net ) 6// 7// Any parts of this program derived from the xMule, lMule or eMule project, 8// or contributed by third-party developers are copyrighted by their 9// respective authors. 10// 11// This program is free software; you can redistribute it and/or modify 12// it under the terms of the GNU General Public License as published by 13// the Free Software Foundation; either version 2 of the License, or 14// (at your option) any later version. 15// 16// This program is distributed in the hope that it will be useful, 17// but WITHOUT ANY WARRANTY; without even the implied warranty of 18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19// GNU General Public License for more details. 20// 21// You should have received a copy of the GNU General Public License 22// along with this program; if not, write to the Free Software 23// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 24// 25 26/* This class supports obfuscation and encryption for a *Mule tcp connection. 27 Right now only basic obfusication is supported, but this can be expanded, as their is a 28 dedicated handshake to negotiate the encryption method used. 29 30 Please note, even if obfuscation uses encryption methods, it does not fulfill cryptographic standards since it 31 doesn't use secret (and for rc4 important: unique) keys 32*/ 33 34#ifndef __ENCRYPTEDSTREAMSOCKET_H__ 35#define __ENCRYPTEDSTREAMSOCKET_H__ 36 37#include <wx/wx.h> 38#include <wx/string.h> 39 40// cryptoPP used for DH integer calculations 41#include "CryptoPP_Inc.h" // Needed for Crypto functions 42#include "Proxy.h" 43#include "Types.h" 44 45#include "RC4Encrypt.h" 46 47#define ERR_WRONGHEADER 0x01 48#define ERR_TOOBIG 0x02 49#define ERR_ENCRYPTION 0x03 50#define ERR_ENCRYPTION_NOTALLOWED 0x04 51 52enum EStreamCryptState { 53 ECS_NONE = 0, // Disabled or not available 54 ECS_UNKNOWN, // Incoming connection, will test the first incoming data for encrypted protocol 55 ECS_PENDING, // Outgoing connection, will start sending encryption protocol 56 ECS_PENDING_SERVER, // Outgoing serverconnection, will start sending encryption protocol 57 ECS_NEGOTIATING, // Encryption supported, handshake still uncompleted 58 ECS_ENCRYPTING // Encryption enabled 59}; 60 61enum ENegotiatingState { 62 ONS_NONE, 63 64 ONS_BASIC_CLIENTA_RANDOMPART, 65 ONS_BASIC_CLIENTA_MAGICVALUE, 66 ONS_BASIC_CLIENTA_METHODTAGSPADLEN, 67 ONS_BASIC_CLIENTA_PADDING, 68 69 ONS_BASIC_CLIENTB_MAGICVALUE, 70 ONS_BASIC_CLIENTB_METHODTAGSPADLEN, 71 ONS_BASIC_CLIENTB_PADDING, 72 73 ONS_BASIC_SERVER_DHANSWER, 74 ONS_BASIC_SERVER_MAGICVALUE, 75 ONS_BASIC_SERVER_METHODTAGSPADLEN, 76 ONS_BASIC_SERVER_PADDING, 77 ONS_BASIC_SERVER_DELAYEDSENDING, 78 79 ONS_COMPLETE 80}; 81 82enum EEncryptionMethods { 83 ENM_OBFUSCATION = 0x00 84}; 85 86 87class CEncryptedStreamSocket : public CSocketClientProxy 88{ 89public: 90 CEncryptedStreamSocket(wxSocketFlags flags = wxSOCKET_NONE, const CProxyData *proxyData = NULL); 91 virtual ~CEncryptedStreamSocket(); 92 93 void SetConnectionEncryption(bool bEnabled, const uint8_t *pTargetClientHash, bool bServerConnection); 94 95 //! Indicates how many bytes were received including obfuscation, 96 //! so that the parent knows if the receive limit was reached 97 uint32_t GetRealReceivedBytes() const { return m_nObfusicationBytesReceived; } 98 99 bool IsObfusicating() const { return m_StreamCryptState == ECS_ENCRYPTING && m_EncryptionMethod == ENM_OBFUSCATION; } 100 bool IsServerCryptEnabledConnection() const { return m_bServerCrypt; } 101 102 uint8_t m_dbgbyEncryptionSupported; 103 uint8_t m_dbgbyEncryptionRequested; 104 uint8_t m_dbgbyEncryptionMethodSet; 105 106protected: 107 int Write(const void* lpBuf, uint32_t nBufLen); 108 int Read(void* lpBuf, uint32_t nBufLen); 109 110 virtual void OnError(int /*nErrorCode*/) {}; 111 virtual void OnSend(int nErrorCode); 112 113 wxString DbgGetIPString(); 114 void CryptPrepareSendData(uint8_t* pBuffer, uint32_t nLen); 115 bool IsEncryptionLayerReady(); 116 uint8_t GetSemiRandomNotProtocolMarker() const; 117 118 uint32_t m_nObfusicationBytesReceived; 119 EStreamCryptState m_StreamCryptState; 120 EEncryptionMethods m_EncryptionMethod; 121 bool m_bFullReceive; 122 bool m_bServerCrypt; 123 124private: 125 int Negotiate(const uint8_t* pBuffer, uint32_t nLen); 126 void StartNegotiation(bool bOutgoing); 127 int SendNegotiatingData(const void *lpBuf, uint32_t nBufLen, uint32_t nStartCryptFromByte = 0, bool bDelaySend = false); 128 129 ENegotiatingState m_NegotiatingState; 130 CRC4EncryptableBuffer m_pfiReceiveBuffer; 131 uint32_t m_nReceiveBytesWanted; 132 CRC4EncryptableBuffer m_pfiSendBuffer; 133 uint32_t m_nRandomKeyPart; 134 CryptoPP::Integer m_cryptDHA; 135}; 136 137#endif // __ENCRYPTEDSTREAMSOCKET_H__ 138