1 /*
2 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 #include "encryptedauthenticate.h"
7
8 #include <QRandomGenerator>
9 #include <algorithm>
10
11 #include "encryptedpacketsocket.h"
12 #include "functions.h"
13 #include "rc4encryptor.h"
14 #include <net/socks.h>
15 #include <torrent/globals.h>
16 #include <torrent/server.h>
17 #include <util/functions.h>
18 #include <util/log.h>
19
20 using namespace bt;
21
22 namespace mse
23 {
EncryptedAuthenticate(const net::Address & addr,TransportProtocol proto,const SHA1Hash & info_hash,const PeerID & peer_id,PeerConnector::WPtr pcon)24 EncryptedAuthenticate::EncryptedAuthenticate(const net::Address &addr,
25 TransportProtocol proto,
26 const SHA1Hash &info_hash,
27 const PeerID &peer_id,
28 PeerConnector::WPtr pcon)
29 : Authenticate(addr, proto, info_hash, peer_id, pcon)
30 {
31 mse::GeneratePublicPrivateKey(xa, ya);
32 state = NOT_CONNECTED;
33 buf_size = 0;
34 our_rc4 = nullptr;
35 vc_off = 0;
36 dec_bytes = 0;
37 crypto_select = 0;
38 pad_D_len = 0;
39 end_of_crypto_handshake = 0;
40 // Out(SYS_CON|LOG_DEBUG) << "EncryptedAuthenticate : " << ip << ":" << port << endl;
41 }
42
~EncryptedAuthenticate()43 EncryptedAuthenticate::~EncryptedAuthenticate()
44 {
45 delete our_rc4;
46 }
47
connected()48 void EncryptedAuthenticate::connected()
49 {
50 // we are connected so send ya and some padding
51 Uint8 tmp[608];
52 ya.toBuffer(tmp, 96);
53 sock->sendData(tmp, 96 + QRandomGenerator::global()->bounded(512));
54 state = SENT_YA;
55 }
56
57 /*
58 1 A->B: Diffie Hellman Ya, PadA
59 2 B->A: Diffie Hellman Yb, PadB
60 3 A->B: HASH('req1', S), HASH('req2', SKEY) xor HASH('req3', S), ENCRYPT(VC, crypto_provide, len(PadC), PadC, len(IA)), ENCRYPT(IA)
61 4 B->A: ENCRYPT(VC, crypto_select, len(padD), padD), ENCRYPT2(Payload Stream)
62 5 A->B: ENCRYPT2(Payload Stream)
63 */
64
handleYB()65 void EncryptedAuthenticate::handleYB()
66 {
67 // if you can't sent 96 bytes you are not worth the effort
68 if (buf_size < 96) {
69 Out(SYS_CON | LOG_DEBUG) << "Not enough data received, encrypted authentication failed" << endl;
70 onFinish(false);
71 return;
72 }
73
74 // read Yb
75 yb = BigInt::fromBuffer(buf, 96);
76
77 // calculate s
78 s = mse::DHSecret(xa, yb);
79
80 state = GOT_YB;
81 // now we must send line 3
82 Uint8 tmp_buf[120]; // temporary buffer
83 bt::SHA1Hash h1, h2; // temporary hash
84
85 // generate and send the first hash
86 memcpy(tmp_buf, "req1", 4);
87 s.toBuffer(tmp_buf + 4, 96);
88 h1 = SHA1Hash::generate(tmp_buf, 100);
89 sock->sendData(h1.getData(), 20);
90
91 // generate second and third hash and xor them
92 memcpy(tmp_buf, "req2", 4);
93 memcpy(tmp_buf + 4, info_hash.getData(), 20);
94 h1 = SHA1Hash::generate(tmp_buf, 24);
95
96 memcpy(tmp_buf, "req3", 4);
97 s.toBuffer(tmp_buf + 4, 96);
98 h2 = SHA1Hash::generate(tmp_buf, 100);
99 sock->sendData((h1 ^ h2).getData(), 20);
100
101 // now we enter encrypted mode the keys are :
102 // HASH('keyA', S, SKEY) for the encryption key
103 // HASH('keyB', S, SKEY) for the decryption key
104 enc = mse::EncryptionKey(true, s, info_hash);
105 dec = mse::EncryptionKey(false, s, info_hash);
106
107 our_rc4 = new RC4Encryptor(dec, enc);
108
109 // now we must send ENCRYPT(VC, crypto_provide, len(PadC), PadC, len(IA))
110 memset(tmp_buf, 0, 16); // VC are 8 0x00's
111 if (bt::ServerInterface::unencryptedConnectionsAllowed())
112 tmp_buf[11] = 0x03; // we support both plain text and rc4
113 else
114 tmp_buf[11] = 0x02;
115 WriteUint16(tmp_buf, 12, 0x0000); // no padC
116 WriteUint16(tmp_buf, 14, 68); // length of IA, which will be the bittorrent handshake
117 // send IA which is the handshake
118 makeHandshake(tmp_buf + 16, info_hash, our_peer_id);
119 sock->sendData(our_rc4->encrypt(tmp_buf, 84), 84);
120
121 // search for the encrypted VC in the data
122 findVC();
123 }
124
findVC()125 void EncryptedAuthenticate::findVC()
126 {
127 Uint8 vc[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
128
129 RC4Encryptor rc4(enc, dec);
130 memcpy(vc, rc4.encrypt(vc, 8), 8);
131
132 Uint32 max_i = buf_size - 8;
133 for (Uint32 i = 96; i < max_i; i++) {
134 if (vc[0] == buf[i] && memcmp(buf + i, vc, 8) == 0) {
135 state = FOUND_VC;
136 vc_off = i;
137 handleCryptoSelect();
138 return;
139 }
140 }
141
142 // we haven't found it in the first 616 bytes (96 + max 512 padding + 8 bytes VC)
143 if (buf_size >= 616) {
144 onFinish(false);
145 }
146 }
147
handleCryptoSelect()148 void EncryptedAuthenticate::handleCryptoSelect()
149 {
150 // not enough data available so lets come back later
151 if (vc_off + 14 >= buf_size)
152 return;
153
154 // now decrypt the first 14 bytes
155 our_rc4->decrypt(buf + vc_off, 14);
156 // check the VC
157 for (Uint32 i = vc_off; i < vc_off + 8; i++) {
158 if (buf[i]) {
159 Out(SYS_CON | LOG_DEBUG) << "Invalid VC " << endl;
160 onFinish(false);
161 return;
162 }
163 }
164
165 crypto_select = ReadUint32(buf, vc_off + 8);
166 pad_D_len = ReadUint16(buf, vc_off + 12);
167 if (pad_D_len > 512) {
168 Out(SYS_CON | LOG_DEBUG) << "Invalid pad D length" << endl;
169 onFinish(false);
170 return;
171 }
172
173 end_of_crypto_handshake = vc_off + 14 + pad_D_len;
174 if (!(vc_off + 14 + pad_D_len < buf_size)) {
175 // padD is not complete, wait for that
176 state = WAIT_FOR_PAD_D;
177 return;
178 }
179
180 handlePadD();
181 }
182
handlePadD()183 void EncryptedAuthenticate::handlePadD()
184 {
185 // decrypt the padding
186 our_rc4->decrypt(buf + (vc_off + 14), pad_D_len);
187
188 if (crypto_select & 0x00000001) { // plain_text selected
189 delete our_rc4;
190 our_rc4 = nullptr;
191 } else if (crypto_select & 0x00000002) { // now it must be rc4 if not exit
192 sock->setRC4Encryptor(our_rc4);
193 our_rc4 = nullptr;
194 } else { // we don't support anything else so error out
195 onFinish(false);
196 return;
197 }
198
199 // noz we wait for the normal handshake
200 state = NORMAL_HANDSHAKE;
201 // if we have read more then the crypto handshake, reinsert it
202 if (buf_size > vc_off + 14 + pad_D_len) {
203 Uint32 off = vc_off + 14 + pad_D_len;
204 sock->reinsert(buf + off, buf_size - off);
205 Authenticate::onReadyRead();
206 }
207 }
208
onReadyRead()209 void EncryptedAuthenticate::onReadyRead()
210 {
211 if (finished)
212 return;
213
214 if (socks) {
215 switch (socks->onReadyToRead()) {
216 case net::Socks::FAILED:
217 Out(SYS_CON | LOG_NOTICE) << "Failed to connect to host via socks server " << endl;
218 onFinish(false);
219 break;
220 case net::Socks::CONNECTED:
221 // connection established, so get rid of socks shit
222 delete socks;
223 socks = nullptr;
224 connected();
225 if (sock->bytesAvailable() > 0)
226 onReadyRead();
227 break;
228 default:
229 break;
230 }
231 return;
232 }
233
234 Uint32 ba = sock->bytesAvailable();
235 if (ba == 0) {
236 onFinish(false);
237 return;
238 }
239
240 if (state != NORMAL_HANDSHAKE) {
241 if (buf_size + ba > MAX_EA_BUF_SIZE)
242 ba = MAX_EA_BUF_SIZE - buf_size;
243
244 // do not read past the end of padD
245 if (pad_D_len > 0 && buf_size + ba > vc_off + 14 + pad_D_len)
246 ba = (vc_off + 14 + pad_D_len) - buf_size;
247 // read data
248 buf_size += sock->readData(buf + buf_size, ba);
249 }
250
251 switch (state) {
252 case SENT_YA:
253 if (ba > 608) {
254 onFinish(false);
255 } else {
256 handleYB();
257 }
258 break;
259 case GOT_YB:
260 findVC();
261 break;
262 case FOUND_VC:
263 handleCryptoSelect();
264 break;
265 case WAIT_FOR_PAD_D:
266 handlePadD();
267 break;
268 case NORMAL_HANDSHAKE:
269 // let AuthenticateBase deal with the data
270 AuthenticateBase::onReadyRead();
271 break;
272 default:
273 break;
274 };
275 }
276
277 }
278