File indexing completed on 2025-01-05 04:37:18
0001 /* 0002 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "encryptedauthenticate.h" 0007 0008 #include <QRandomGenerator> 0009 #include <algorithm> 0010 0011 #include "encryptedpacketsocket.h" 0012 #include "functions.h" 0013 #include "rc4encryptor.h" 0014 #include <net/socks.h> 0015 #include <torrent/globals.h> 0016 #include <torrent/server.h> 0017 #include <util/functions.h> 0018 #include <util/log.h> 0019 0020 using namespace bt; 0021 0022 namespace mse 0023 { 0024 EncryptedAuthenticate::EncryptedAuthenticate(const net::Address &addr, 0025 TransportProtocol proto, 0026 const SHA1Hash &info_hash, 0027 const PeerID &peer_id, 0028 PeerConnector::WPtr pcon) 0029 : Authenticate(addr, proto, info_hash, peer_id, pcon) 0030 { 0031 mse::GeneratePublicPrivateKey(xa, ya); 0032 state = NOT_CONNECTED; 0033 buf_size = 0; 0034 our_rc4 = nullptr; 0035 vc_off = 0; 0036 dec_bytes = 0; 0037 crypto_select = 0; 0038 pad_D_len = 0; 0039 end_of_crypto_handshake = 0; 0040 // Out(SYS_CON|LOG_DEBUG) << "EncryptedAuthenticate : " << ip << ":" << port << endl; 0041 } 0042 0043 EncryptedAuthenticate::~EncryptedAuthenticate() 0044 { 0045 delete our_rc4; 0046 } 0047 0048 void EncryptedAuthenticate::connected() 0049 { 0050 // we are connected so send ya and some padding 0051 Uint8 tmp[608]; 0052 ya.toBuffer(tmp, 96); 0053 sock->sendData(tmp, 96 + QRandomGenerator::global()->bounded(512)); 0054 state = SENT_YA; 0055 } 0056 0057 /* 0058 1 A->B: Diffie Hellman Ya, PadA 0059 2 B->A: Diffie Hellman Yb, PadB 0060 3 A->B: HASH('req1', S), HASH('req2', SKEY) xor HASH('req3', S), ENCRYPT(VC, crypto_provide, len(PadC), PadC, len(IA)), ENCRYPT(IA) 0061 4 B->A: ENCRYPT(VC, crypto_select, len(padD), padD), ENCRYPT2(Payload Stream) 0062 5 A->B: ENCRYPT2(Payload Stream) 0063 */ 0064 0065 void EncryptedAuthenticate::handleYB() 0066 { 0067 // if you can't sent 96 bytes you are not worth the effort 0068 if (buf_size < 96) { 0069 Out(SYS_CON | LOG_DEBUG) << "Not enough data received, encrypted authentication failed" << endl; 0070 onFinish(false); 0071 return; 0072 } 0073 0074 // read Yb 0075 yb = BigInt::fromBuffer(buf, 96); 0076 0077 // calculate s 0078 s = mse::DHSecret(xa, yb); 0079 0080 state = GOT_YB; 0081 // now we must send line 3 0082 Uint8 tmp_buf[120]; // temporary buffer 0083 bt::SHA1Hash h1, h2; // temporary hash 0084 0085 // generate and send the first hash 0086 memcpy(tmp_buf, "req1", 4); 0087 s.toBuffer(tmp_buf + 4, 96); 0088 h1 = SHA1Hash::generate(tmp_buf, 100); 0089 sock->sendData(h1.getData(), 20); 0090 0091 // generate second and third hash and xor them 0092 memcpy(tmp_buf, "req2", 4); 0093 memcpy(tmp_buf + 4, info_hash.getData(), 20); 0094 h1 = SHA1Hash::generate(tmp_buf, 24); 0095 0096 memcpy(tmp_buf, "req3", 4); 0097 s.toBuffer(tmp_buf + 4, 96); 0098 h2 = SHA1Hash::generate(tmp_buf, 100); 0099 sock->sendData((h1 ^ h2).getData(), 20); 0100 0101 // now we enter encrypted mode the keys are : 0102 // HASH('keyA', S, SKEY) for the encryption key 0103 // HASH('keyB', S, SKEY) for the decryption key 0104 enc = mse::EncryptionKey(true, s, info_hash); 0105 dec = mse::EncryptionKey(false, s, info_hash); 0106 0107 our_rc4 = new RC4Encryptor(dec, enc); 0108 0109 // now we must send ENCRYPT(VC, crypto_provide, len(PadC), PadC, len(IA)) 0110 memset(tmp_buf, 0, 16); // VC are 8 0x00's 0111 if (bt::ServerInterface::unencryptedConnectionsAllowed()) 0112 tmp_buf[11] = 0x03; // we support both plain text and rc4 0113 else 0114 tmp_buf[11] = 0x02; 0115 WriteUint16(tmp_buf, 12, 0x0000); // no padC 0116 WriteUint16(tmp_buf, 14, 68); // length of IA, which will be the bittorrent handshake 0117 // send IA which is the handshake 0118 makeHandshake(tmp_buf + 16, info_hash, our_peer_id); 0119 sock->sendData(our_rc4->encrypt(tmp_buf, 84), 84); 0120 0121 // search for the encrypted VC in the data 0122 findVC(); 0123 } 0124 0125 void EncryptedAuthenticate::findVC() 0126 { 0127 Uint8 vc[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 0128 0129 RC4Encryptor rc4(enc, dec); 0130 memcpy(vc, rc4.encrypt(vc, 8), 8); 0131 0132 Uint32 max_i = buf_size - 8; 0133 for (Uint32 i = 96; i < max_i; i++) { 0134 if (vc[0] == buf[i] && memcmp(buf + i, vc, 8) == 0) { 0135 state = FOUND_VC; 0136 vc_off = i; 0137 handleCryptoSelect(); 0138 return; 0139 } 0140 } 0141 0142 // we haven't found it in the first 616 bytes (96 + max 512 padding + 8 bytes VC) 0143 if (buf_size >= 616) { 0144 onFinish(false); 0145 } 0146 } 0147 0148 void EncryptedAuthenticate::handleCryptoSelect() 0149 { 0150 // not enough data available so lets come back later 0151 if (vc_off + 14 >= buf_size) 0152 return; 0153 0154 // now decrypt the first 14 bytes 0155 our_rc4->decrypt(buf + vc_off, 14); 0156 // check the VC 0157 for (Uint32 i = vc_off; i < vc_off + 8; i++) { 0158 if (buf[i]) { 0159 Out(SYS_CON | LOG_DEBUG) << "Invalid VC " << endl; 0160 onFinish(false); 0161 return; 0162 } 0163 } 0164 0165 crypto_select = ReadUint32(buf, vc_off + 8); 0166 pad_D_len = ReadUint16(buf, vc_off + 12); 0167 if (pad_D_len > 512) { 0168 Out(SYS_CON | LOG_DEBUG) << "Invalid pad D length" << endl; 0169 onFinish(false); 0170 return; 0171 } 0172 0173 end_of_crypto_handshake = vc_off + 14 + pad_D_len; 0174 if (!(vc_off + 14 + pad_D_len < buf_size)) { 0175 // padD is not complete, wait for that 0176 state = WAIT_FOR_PAD_D; 0177 return; 0178 } 0179 0180 handlePadD(); 0181 } 0182 0183 void EncryptedAuthenticate::handlePadD() 0184 { 0185 // decrypt the padding 0186 our_rc4->decrypt(buf + (vc_off + 14), pad_D_len); 0187 0188 if (crypto_select & 0x00000001) { // plain_text selected 0189 delete our_rc4; 0190 our_rc4 = nullptr; 0191 } else if (crypto_select & 0x00000002) { // now it must be rc4 if not exit 0192 sock->setRC4Encryptor(our_rc4); 0193 our_rc4 = nullptr; 0194 } else { // we don't support anything else so error out 0195 onFinish(false); 0196 return; 0197 } 0198 0199 // noz we wait for the normal handshake 0200 state = NORMAL_HANDSHAKE; 0201 // if we have read more then the crypto handshake, reinsert it 0202 if (buf_size > vc_off + 14 + pad_D_len) { 0203 Uint32 off = vc_off + 14 + pad_D_len; 0204 sock->reinsert(buf + off, buf_size - off); 0205 Authenticate::onReadyRead(); 0206 } 0207 } 0208 0209 void EncryptedAuthenticate::onReadyRead() 0210 { 0211 if (finished) 0212 return; 0213 0214 if (socks) { 0215 switch (socks->onReadyToRead()) { 0216 case net::Socks::FAILED: 0217 Out(SYS_CON | LOG_NOTICE) << "Failed to connect to host via socks server " << endl; 0218 onFinish(false); 0219 break; 0220 case net::Socks::CONNECTED: 0221 // connection established, so get rid of socks shit 0222 delete socks; 0223 socks = nullptr; 0224 connected(); 0225 if (sock->bytesAvailable() > 0) 0226 onReadyRead(); 0227 break; 0228 default: 0229 break; 0230 } 0231 return; 0232 } 0233 0234 Uint32 ba = sock->bytesAvailable(); 0235 if (ba == 0) { 0236 onFinish(false); 0237 return; 0238 } 0239 0240 if (state != NORMAL_HANDSHAKE) { 0241 if (buf_size + ba > MAX_EA_BUF_SIZE) 0242 ba = MAX_EA_BUF_SIZE - buf_size; 0243 0244 // do not read past the end of padD 0245 if (pad_D_len > 0 && buf_size + ba > vc_off + 14 + pad_D_len) 0246 ba = (vc_off + 14 + pad_D_len) - buf_size; 0247 // read data 0248 buf_size += sock->readData(buf + buf_size, ba); 0249 } 0250 0251 switch (state) { 0252 case SENT_YA: 0253 if (ba > 608) { 0254 onFinish(false); 0255 } else { 0256 handleYB(); 0257 } 0258 break; 0259 case GOT_YB: 0260 findVC(); 0261 break; 0262 case FOUND_VC: 0263 handleCryptoSelect(); 0264 break; 0265 case WAIT_FOR_PAD_D: 0266 handlePadD(); 0267 break; 0268 case NORMAL_HANDSHAKE: 0269 // let AuthenticateBase deal with the data 0270 AuthenticateBase::onReadyRead(); 0271 break; 0272 default: 0273 break; 0274 }; 0275 } 0276 0277 } 0278 0279 #include "moc_encryptedauthenticate.cpp"