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"