librats 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/binding.gyp +1 -0
- package/lib/index.d.ts +2 -1
- package/native-src/3rdparty/android/ifaddrs-android.c +600 -0
- package/native-src/3rdparty/android/ifaddrs-android.h +54 -0
- package/native-src/CMakeLists.txt +360 -0
- package/native-src/LICENSE +21 -0
- package/native-src/src/bencode.cpp +485 -0
- package/native-src/src/bencode.h +145 -0
- package/native-src/src/bittorrent.cpp +3682 -0
- package/native-src/src/bittorrent.h +731 -0
- package/native-src/src/dht.cpp +2460 -0
- package/native-src/src/dht.h +508 -0
- package/native-src/src/encrypted_socket.cpp +817 -0
- package/native-src/src/encrypted_socket.h +239 -0
- package/native-src/src/file_transfer.cpp +1808 -0
- package/native-src/src/file_transfer.h +567 -0
- package/native-src/src/fs.cpp +639 -0
- package/native-src/src/fs.h +108 -0
- package/native-src/src/gossipsub.cpp +1137 -0
- package/native-src/src/gossipsub.h +403 -0
- package/native-src/src/ice.cpp +1386 -0
- package/native-src/src/ice.h +328 -0
- package/native-src/src/json.hpp +25526 -0
- package/native-src/src/krpc.cpp +558 -0
- package/native-src/src/krpc.h +145 -0
- package/native-src/src/librats.cpp +2735 -0
- package/native-src/src/librats.h +1732 -0
- package/native-src/src/librats_bittorrent.cpp +167 -0
- package/native-src/src/librats_c.cpp +1333 -0
- package/native-src/src/librats_c.h +239 -0
- package/native-src/src/librats_encryption.cpp +123 -0
- package/native-src/src/librats_file_transfer.cpp +226 -0
- package/native-src/src/librats_gossipsub.cpp +293 -0
- package/native-src/src/librats_ice.cpp +515 -0
- package/native-src/src/librats_logging.cpp +158 -0
- package/native-src/src/librats_mdns.cpp +171 -0
- package/native-src/src/librats_nat.cpp +571 -0
- package/native-src/src/librats_persistence.cpp +815 -0
- package/native-src/src/logger.h +412 -0
- package/native-src/src/mdns.cpp +1178 -0
- package/native-src/src/mdns.h +253 -0
- package/native-src/src/network_utils.cpp +598 -0
- package/native-src/src/network_utils.h +162 -0
- package/native-src/src/noise.cpp +981 -0
- package/native-src/src/noise.h +227 -0
- package/native-src/src/os.cpp +371 -0
- package/native-src/src/os.h +40 -0
- package/native-src/src/rats_export.h +17 -0
- package/native-src/src/sha1.cpp +163 -0
- package/native-src/src/sha1.h +42 -0
- package/native-src/src/socket.cpp +1376 -0
- package/native-src/src/socket.h +309 -0
- package/native-src/src/stun.cpp +484 -0
- package/native-src/src/stun.h +349 -0
- package/native-src/src/threadmanager.cpp +105 -0
- package/native-src/src/threadmanager.h +53 -0
- package/native-src/src/tracker.cpp +1110 -0
- package/native-src/src/tracker.h +268 -0
- package/native-src/src/version.cpp +24 -0
- package/native-src/src/version.h.in +45 -0
- package/native-src/version.rc.in +31 -0
- package/package.json +2 -8
- package/scripts/build-librats.js +59 -12
- package/scripts/prepare-package.js +133 -37
- package/src/librats_node.cpp +46 -1
|
@@ -0,0 +1,817 @@
|
|
|
1
|
+
#include "encrypted_socket.h"
|
|
2
|
+
#include "logger.h"
|
|
3
|
+
#include <algorithm>
|
|
4
|
+
#include <cstring>
|
|
5
|
+
#include <thread>
|
|
6
|
+
#include <chrono>
|
|
7
|
+
|
|
8
|
+
#define LOG_ENCRYPT_DEBUG(message) LOG_DEBUG("encrypt", message)
|
|
9
|
+
#define LOG_ENCRYPT_INFO(message) LOG_INFO("encrypt", message)
|
|
10
|
+
#define LOG_ENCRYPT_WARN(message) LOG_WARN("encrypt", message)
|
|
11
|
+
#define LOG_ENCRYPT_ERROR(message) LOG_ERROR("encrypt", message)
|
|
12
|
+
|
|
13
|
+
namespace librats {
|
|
14
|
+
|
|
15
|
+
// Message framing constants
|
|
16
|
+
constexpr uint32_t NOISE_MESSAGE_MAGIC = 0x4E4F4953; // "NOIS" in little endian
|
|
17
|
+
constexpr uint32_t HANDSHAKE_MESSAGE_MAGIC = 0x48534B48; // "HSKH" in little endian
|
|
18
|
+
constexpr size_t MESSAGE_HEADER_SIZE = 8; // 4 bytes magic + 4 bytes length
|
|
19
|
+
|
|
20
|
+
//=============================================================================
|
|
21
|
+
// EncryptedSocket Implementation
|
|
22
|
+
//=============================================================================
|
|
23
|
+
|
|
24
|
+
EncryptedSocket::EncryptedSocket() = default;
|
|
25
|
+
|
|
26
|
+
EncryptedSocket::~EncryptedSocket() {
|
|
27
|
+
clear_all_sockets();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
bool EncryptedSocket::initialize_as_initiator(socket_t socket, const NoiseKey& static_private_key) {
|
|
31
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
32
|
+
|
|
33
|
+
auto session = std::make_unique<SocketSession>(socket);
|
|
34
|
+
if (!session->session->initialize_as_initiator(static_private_key)) {
|
|
35
|
+
LOG_ENCRYPT_ERROR("Failed to initialize noise session as initiator for socket " << socket);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
session->is_encrypted = true;
|
|
40
|
+
sessions_[socket] = std::move(session);
|
|
41
|
+
|
|
42
|
+
LOG_ENCRYPT_INFO("Initialized encrypted socket " << socket << " as initiator");
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
bool EncryptedSocket::initialize_as_responder(socket_t socket, const NoiseKey& static_private_key) {
|
|
47
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
48
|
+
|
|
49
|
+
auto session = std::make_unique<SocketSession>(socket);
|
|
50
|
+
if (!session->session->initialize_as_responder(static_private_key)) {
|
|
51
|
+
LOG_ENCRYPT_ERROR("Failed to initialize noise session as responder for socket " << socket);
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
session->is_encrypted = true;
|
|
56
|
+
sessions_[socket] = std::move(session);
|
|
57
|
+
|
|
58
|
+
LOG_ENCRYPT_INFO("Initialized encrypted socket " << socket << " as responder");
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
bool EncryptedSocket::is_encrypted(socket_t socket) const {
|
|
63
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
64
|
+
const auto* session = get_session(socket);
|
|
65
|
+
return session && session->is_encrypted;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
bool EncryptedSocket::is_handshake_completed(socket_t socket) const {
|
|
69
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
70
|
+
const auto* session = get_session(socket);
|
|
71
|
+
return session && session->session->is_handshake_completed();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
bool EncryptedSocket::has_handshake_failed(socket_t socket) const {
|
|
75
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
76
|
+
const auto* session = get_session(socket);
|
|
77
|
+
return session && session->session->has_handshake_failed();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
bool EncryptedSocket::send_handshake_message(socket_t socket, const std::vector<uint8_t>& payload) {
|
|
81
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
82
|
+
auto* session = get_session(socket);
|
|
83
|
+
if (!session) {
|
|
84
|
+
LOG_ENCRYPT_ERROR("No session found for socket " << socket);
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
auto handshake_data = session->session->create_handshake_message(payload);
|
|
90
|
+
if (handshake_data.empty() && !session->session->is_handshake_completed()) {
|
|
91
|
+
LOG_ENCRYPT_ERROR("Failed to create handshake message for socket " << socket);
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!handshake_data.empty()) {
|
|
96
|
+
auto framed_message = frame_message(handshake_data);
|
|
97
|
+
|
|
98
|
+
LOG_ENCRYPT_DEBUG("Created framed message with " << framed_message.size() << " bytes, noise data was " << handshake_data.size() << " bytes");
|
|
99
|
+
LOG_ENCRYPT_DEBUG("First 12 bytes of framed message: " << std::hex
|
|
100
|
+
<< "0x" << std::setfill('0') << std::setw(2) << (unsigned)framed_message[0]
|
|
101
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)framed_message[1]
|
|
102
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)framed_message[2]
|
|
103
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)framed_message[3] << " "
|
|
104
|
+
<< "0x" << std::setfill('0') << std::setw(2) << (unsigned)framed_message[4]
|
|
105
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)framed_message[5]
|
|
106
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)framed_message[6]
|
|
107
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)framed_message[7] << " "
|
|
108
|
+
<< "0x" << std::setfill('0') << std::setw(2) << (unsigned)framed_message[8]
|
|
109
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)framed_message[9]
|
|
110
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)framed_message[10]
|
|
111
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)framed_message[11]);
|
|
112
|
+
|
|
113
|
+
// Add handshake magic to distinguish from regular messages (convert to network byte order)
|
|
114
|
+
std::vector<uint8_t> handshake_message;
|
|
115
|
+
handshake_message.resize(4);
|
|
116
|
+
uint32_t handshake_magic_be = htonl(HANDSHAKE_MESSAGE_MAGIC);
|
|
117
|
+
std::memcpy(handshake_message.data(), &handshake_magic_be, 4);
|
|
118
|
+
handshake_message.insert(handshake_message.end(), framed_message.begin(), framed_message.end());
|
|
119
|
+
|
|
120
|
+
std::string data_str(handshake_message.begin(), handshake_message.end());
|
|
121
|
+
LOG_ENCRYPT_DEBUG("Sending total handshake message: " << handshake_message.size() << " bytes");
|
|
122
|
+
LOG_ENCRYPT_DEBUG("Complete message first 16 bytes: " << std::hex
|
|
123
|
+
<< "0x" << std::setfill('0') << std::setw(2) << (unsigned)handshake_message[0]
|
|
124
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[1]
|
|
125
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[2]
|
|
126
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[3] << " "
|
|
127
|
+
<< "0x" << std::setfill('0') << std::setw(2) << (unsigned)handshake_message[4]
|
|
128
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[5]
|
|
129
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[6]
|
|
130
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[7] << " "
|
|
131
|
+
<< "0x" << std::setfill('0') << std::setw(2) << (unsigned)handshake_message[8]
|
|
132
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[9]
|
|
133
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[10]
|
|
134
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[11] << " "
|
|
135
|
+
<< "0x" << std::setfill('0') << std::setw(2) << (unsigned)handshake_message[12]
|
|
136
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[13]
|
|
137
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[14]
|
|
138
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)handshake_message[15]);
|
|
139
|
+
int sent = send_tcp_string(socket, data_str);
|
|
140
|
+
|
|
141
|
+
if (sent <= 0) {
|
|
142
|
+
LOG_ENCRYPT_ERROR("Failed to send handshake message to socket " << socket);
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
LOG_ENCRYPT_DEBUG("Sent handshake message (" << handshake_data.size() << " bytes) to socket " << socket);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return true;
|
|
150
|
+
|
|
151
|
+
} catch (const std::exception& e) {
|
|
152
|
+
LOG_ENCRYPT_ERROR("Exception in send_handshake_message: " << e.what());
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
std::vector<uint8_t> EncryptedSocket::receive_handshake_message(socket_t socket) {
|
|
158
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
159
|
+
auto* session = get_session(socket);
|
|
160
|
+
if (!session) {
|
|
161
|
+
LOG_ENCRYPT_ERROR("No session found for socket " << socket);
|
|
162
|
+
return {};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
// First, read the handshake magic (4 bytes)
|
|
167
|
+
LOG_ENCRYPT_DEBUG("Attempting to receive handshake magic on socket " << socket);
|
|
168
|
+
std::string magic_data = receive_exact_bytes(socket, 4);
|
|
169
|
+
if (magic_data.size() < 4) {
|
|
170
|
+
LOG_ENCRYPT_DEBUG("Failed to receive complete handshake magic, got " << magic_data.size() << " bytes");
|
|
171
|
+
return {};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Check handshake magic
|
|
175
|
+
uint32_t received_magic;
|
|
176
|
+
std::memcpy(&received_magic, magic_data.data(), 4);
|
|
177
|
+
received_magic = ntohl(received_magic); // Convert from network byte order
|
|
178
|
+
if (received_magic != HANDSHAKE_MESSAGE_MAGIC) {
|
|
179
|
+
LOG_ENCRYPT_WARN("Received data is not a handshake message (magic: 0x" << std::hex << received_magic << ")");
|
|
180
|
+
return {};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Now read the noise frame header (8 bytes)
|
|
184
|
+
LOG_ENCRYPT_DEBUG("Reading noise frame header on socket " << socket);
|
|
185
|
+
std::string frame_header = receive_exact_bytes(socket, 8);
|
|
186
|
+
LOG_ENCRYPT_DEBUG("Received frame header: " << frame_header.size() << " bytes (expected 8)");
|
|
187
|
+
if (frame_header.size() < 8) {
|
|
188
|
+
LOG_ENCRYPT_ERROR("Failed to receive complete frame header, got " << frame_header.size() << " bytes");
|
|
189
|
+
return {};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Parse the noise message length from the frame header
|
|
193
|
+
uint32_t noise_magic;
|
|
194
|
+
uint32_t noise_length;
|
|
195
|
+
std::memcpy(&noise_magic, frame_header.data(), 4);
|
|
196
|
+
std::memcpy(&noise_length, frame_header.data() + 4, 4);
|
|
197
|
+
|
|
198
|
+
LOG_ENCRYPT_DEBUG("Raw frame header bytes: " << std::hex
|
|
199
|
+
<< "0x" << std::setfill('0') << std::setw(2) << (unsigned)(uint8_t)frame_header[0]
|
|
200
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)(uint8_t)frame_header[1]
|
|
201
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)(uint8_t)frame_header[2]
|
|
202
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)(uint8_t)frame_header[3] << " "
|
|
203
|
+
<< "0x" << std::setfill('0') << std::setw(2) << (unsigned)(uint8_t)frame_header[4]
|
|
204
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)(uint8_t)frame_header[5]
|
|
205
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)(uint8_t)frame_header[6]
|
|
206
|
+
<< std::setfill('0') << std::setw(2) << (unsigned)(uint8_t)frame_header[7]);
|
|
207
|
+
|
|
208
|
+
// Convert from network byte order (big endian) to host byte order
|
|
209
|
+
noise_magic = ntohl(noise_magic);
|
|
210
|
+
noise_length = ntohl(noise_length);
|
|
211
|
+
|
|
212
|
+
LOG_ENCRYPT_DEBUG("Parsed noise magic: 0x" << std::hex << noise_magic << ", length: " << std::dec << noise_length);
|
|
213
|
+
|
|
214
|
+
if (noise_magic != NOISE_MESSAGE_MAGIC) {
|
|
215
|
+
LOG_ENCRYPT_ERROR("Invalid noise message magic in frame header: 0x" << std::hex << noise_magic << " (expected 0x" << NOISE_MESSAGE_MAGIC << ")");
|
|
216
|
+
return {};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (noise_length > NOISE_MAX_MESSAGE_SIZE) {
|
|
220
|
+
LOG_ENCRYPT_ERROR("Noise message length too large: " << noise_length);
|
|
221
|
+
return {};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Read the actual noise message data
|
|
225
|
+
LOG_ENCRYPT_DEBUG("Reading " << noise_length << " bytes of noise message data on socket " << socket);
|
|
226
|
+
std::string noise_data = receive_exact_bytes(socket, noise_length);
|
|
227
|
+
if (noise_data.size() < noise_length) {
|
|
228
|
+
LOG_ENCRYPT_ERROR("Failed to receive complete noise message, got " << noise_data.size() << " of " << noise_length << " bytes");
|
|
229
|
+
return {};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Reconstruct the complete framed message
|
|
233
|
+
std::vector<uint8_t> framed_data;
|
|
234
|
+
framed_data.insert(framed_data.end(), frame_header.begin(), frame_header.end());
|
|
235
|
+
framed_data.insert(framed_data.end(), noise_data.begin(), noise_data.end());
|
|
236
|
+
|
|
237
|
+
auto handshake_data = unframe_message(framed_data);
|
|
238
|
+
LOG_ENCRYPT_DEBUG("Successfully received and unframed " << handshake_data.size() << " bytes of handshake data");
|
|
239
|
+
|
|
240
|
+
if (handshake_data.empty()) {
|
|
241
|
+
LOG_ENCRYPT_ERROR("Failed to unframe handshake message");
|
|
242
|
+
return {};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Process handshake message
|
|
246
|
+
auto payload = session->session->process_handshake_message(handshake_data);
|
|
247
|
+
|
|
248
|
+
LOG_ENCRYPT_DEBUG("Received and processed handshake message (" << handshake_data.size() << " bytes) from socket " << socket);
|
|
249
|
+
|
|
250
|
+
return payload;
|
|
251
|
+
|
|
252
|
+
} catch (const std::exception& e) {
|
|
253
|
+
LOG_ENCRYPT_ERROR("Exception in receive_handshake_message: " << e.what());
|
|
254
|
+
return {};
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
bool EncryptedSocket::send_encrypted_data(socket_t socket, const std::vector<uint8_t>& data) {
|
|
259
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
260
|
+
auto* session = get_session(socket);
|
|
261
|
+
if (!session) {
|
|
262
|
+
LOG_ENCRYPT_ERROR("No session found for socket " << socket);
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (!session->session->is_handshake_completed()) {
|
|
267
|
+
LOG_ENCRYPT_ERROR("Cannot send encrypted data: handshake not completed for socket " << socket);
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
try {
|
|
272
|
+
auto encrypted_data = session->session->encrypt_transport_message(data);
|
|
273
|
+
|
|
274
|
+
if (encrypted_data.empty()) {
|
|
275
|
+
LOG_ENCRYPT_ERROR("Failed to encrypt data for socket " << socket);
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
auto framed_message = frame_message(encrypted_data);
|
|
280
|
+
|
|
281
|
+
int sent = send_tcp_data(socket, framed_message);
|
|
282
|
+
if (sent <= 0) {
|
|
283
|
+
LOG_ENCRYPT_ERROR("Failed to send encrypted data to socket " << socket);
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
LOG_ENCRYPT_DEBUG("Sent encrypted data (" << data.size() << " bytes plaintext, " << encrypted_data.size() << " bytes encrypted) to socket " << socket);
|
|
288
|
+
return true;
|
|
289
|
+
|
|
290
|
+
} catch (const std::exception& e) {
|
|
291
|
+
LOG_ENCRYPT_ERROR("Exception in send_encrypted_data: " << e.what());
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
bool EncryptedSocket::send_encrypted_data(socket_t socket, const std::string& data) {
|
|
297
|
+
std::vector<uint8_t> binary_data(data.begin(), data.end());
|
|
298
|
+
return send_encrypted_data(socket, binary_data);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
std::vector<uint8_t> EncryptedSocket::receive_encrypted_data(socket_t socket) {
|
|
302
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
303
|
+
auto* session = get_session(socket);
|
|
304
|
+
if (!session) {
|
|
305
|
+
LOG_ENCRYPT_ERROR("No session found for socket " << socket);
|
|
306
|
+
return std::vector<uint8_t>();
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (!session->session->is_handshake_completed()) {
|
|
310
|
+
LOG_ENCRYPT_ERROR("Cannot receive encrypted data: handshake not completed for socket " << socket);
|
|
311
|
+
return std::vector<uint8_t>();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
try {
|
|
315
|
+
std::vector<uint8_t> raw_data = receive_tcp_data(socket, 4096);
|
|
316
|
+
if (raw_data.empty()) {
|
|
317
|
+
return std::vector<uint8_t>();
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
auto encrypted_data = unframe_message(raw_data);
|
|
321
|
+
|
|
322
|
+
if (encrypted_data.empty()) {
|
|
323
|
+
LOG_ENCRYPT_ERROR("Failed to unframe encrypted message");
|
|
324
|
+
return std::vector<uint8_t>();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
auto decrypted_data = session->session->decrypt_transport_message(encrypted_data);
|
|
328
|
+
|
|
329
|
+
if (decrypted_data.empty()) {
|
|
330
|
+
LOG_ENCRYPT_ERROR("Failed to decrypt data from socket " << socket);
|
|
331
|
+
return std::vector<uint8_t>();
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
LOG_ENCRYPT_DEBUG("Received encrypted data (" << encrypted_data.size() << " bytes encrypted, " << decrypted_data.size() << " bytes plaintext) from socket " << socket);
|
|
335
|
+
|
|
336
|
+
return decrypted_data;
|
|
337
|
+
|
|
338
|
+
} catch (const std::exception& e) {
|
|
339
|
+
LOG_ENCRYPT_ERROR("Exception in receive_encrypted_data: " << e.what());
|
|
340
|
+
return std::vector<uint8_t>();
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
std::string EncryptedSocket::receive_encrypted_data_string(socket_t socket) {
|
|
345
|
+
std::vector<uint8_t> binary_data = receive_encrypted_data(socket);
|
|
346
|
+
if (binary_data.empty()) {
|
|
347
|
+
return "";
|
|
348
|
+
}
|
|
349
|
+
return std::string(binary_data.begin(), binary_data.end());
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
bool EncryptedSocket::send_unencrypted_data(socket_t socket, const std::vector<uint8_t>& data) {
|
|
353
|
+
int sent = send_tcp_data(socket, data);
|
|
354
|
+
return sent > 0;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
bool EncryptedSocket::send_unencrypted_data(socket_t socket, const std::string& data) {
|
|
358
|
+
std::vector<uint8_t> binary_data(data.begin(), data.end());
|
|
359
|
+
return send_unencrypted_data(socket, binary_data);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
std::vector<uint8_t> EncryptedSocket::receive_unencrypted_data(socket_t socket) {
|
|
363
|
+
return receive_tcp_data(socket);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
std::string EncryptedSocket::receive_unencrypted_data_string(socket_t socket) {
|
|
367
|
+
return receive_tcp_string(socket);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
void EncryptedSocket::remove_socket(socket_t socket) {
|
|
371
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
372
|
+
auto it = sessions_.find(socket);
|
|
373
|
+
if (it != sessions_.end()) {
|
|
374
|
+
LOG_ENCRYPT_DEBUG("Removing encrypted socket session for socket " << socket);
|
|
375
|
+
sessions_.erase(it);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
void EncryptedSocket::clear_all_sockets() {
|
|
380
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
381
|
+
LOG_ENCRYPT_INFO("Clearing all encrypted socket sessions (" << sessions_.size() << " sessions)");
|
|
382
|
+
sessions_.clear();
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
NoiseKey EncryptedSocket::generate_static_key() {
|
|
386
|
+
return noise_utils::generate_static_keypair();
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
std::string EncryptedSocket::key_to_string(const NoiseKey& key) {
|
|
390
|
+
return noise_utils::key_to_hex(key);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
NoiseKey EncryptedSocket::string_to_key(const std::string& key_str) {
|
|
394
|
+
return noise_utils::hex_to_key(key_str);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
NoiseRole EncryptedSocket::get_socket_role(socket_t socket) const {
|
|
398
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
399
|
+
const auto* session = get_session(socket);
|
|
400
|
+
if (session) {
|
|
401
|
+
return session->session->get_role();
|
|
402
|
+
}
|
|
403
|
+
return NoiseRole::INITIATOR; // Default
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const NoiseKey& EncryptedSocket::get_remote_static_key(socket_t socket) const {
|
|
407
|
+
std::lock_guard<std::mutex> lock(sessions_mutex_);
|
|
408
|
+
const auto* session = get_session(socket);
|
|
409
|
+
if (session) {
|
|
410
|
+
return session->session->get_remote_static_public_key();
|
|
411
|
+
}
|
|
412
|
+
static NoiseKey empty_key;
|
|
413
|
+
empty_key.fill(0);
|
|
414
|
+
return empty_key;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
EncryptedSocket::SocketSession* EncryptedSocket::get_session(socket_t socket) {
|
|
418
|
+
auto it = sessions_.find(socket);
|
|
419
|
+
return (it != sessions_.end()) ? it->second.get() : nullptr;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const EncryptedSocket::SocketSession* EncryptedSocket::get_session(socket_t socket) const {
|
|
423
|
+
auto it = sessions_.find(socket);
|
|
424
|
+
return (it != sessions_.end()) ? it->second.get() : nullptr;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
std::string EncryptedSocket::receive_exact_bytes(socket_t socket, size_t byte_count) {
|
|
428
|
+
std::string buffer;
|
|
429
|
+
buffer.reserve(byte_count);
|
|
430
|
+
|
|
431
|
+
while (buffer.size() < byte_count) {
|
|
432
|
+
size_t remaining = byte_count - buffer.size();
|
|
433
|
+
std::string chunk = receive_tcp_string(socket, remaining);
|
|
434
|
+
|
|
435
|
+
if (chunk.empty()) {
|
|
436
|
+
// Connection closed or error
|
|
437
|
+
LOG_ENCRYPT_DEBUG("Connection closed or error while reading " << remaining << " remaining bytes");
|
|
438
|
+
|
|
439
|
+
// Mark the session as failed if connection is closed during handshake
|
|
440
|
+
auto* session = get_session(socket);
|
|
441
|
+
if (session && !session->session->is_handshake_completed()) {
|
|
442
|
+
LOG_ENCRYPT_DEBUG("Marking handshake as failed due to connection closure");
|
|
443
|
+
// The session will be cleaned up by the caller
|
|
444
|
+
}
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
buffer.append(chunk);
|
|
449
|
+
LOG_ENCRYPT_DEBUG("Read " << chunk.size() << " bytes, total: " << buffer.size() << "/" << byte_count);
|
|
450
|
+
if (chunk.size() <= 8) { // Log small chunks in detail
|
|
451
|
+
LOG_ENCRYPT_DEBUG("Chunk content: " << std::hex
|
|
452
|
+
<< "0x" << std::setfill('0') << std::setw(2) << (chunk.size() > 0 ? (unsigned)(uint8_t)chunk[0] : 0)
|
|
453
|
+
<< std::setfill('0') << std::setw(2) << (chunk.size() > 1 ? (unsigned)(uint8_t)chunk[1] : 0)
|
|
454
|
+
<< std::setfill('0') << std::setw(2) << (chunk.size() > 2 ? (unsigned)(uint8_t)chunk[2] : 0)
|
|
455
|
+
<< std::setfill('0') << std::setw(2) << (chunk.size() > 3 ? (unsigned)(uint8_t)chunk[3] : 0) << " "
|
|
456
|
+
<< "0x" << std::setfill('0') << std::setw(2) << (chunk.size() > 4 ? (unsigned)(uint8_t)chunk[4] : 0)
|
|
457
|
+
<< std::setfill('0') << std::setw(2) << (chunk.size() > 5 ? (unsigned)(uint8_t)chunk[5] : 0)
|
|
458
|
+
<< std::setfill('0') << std::setw(2) << (chunk.size() > 6 ? (unsigned)(uint8_t)chunk[6] : 0)
|
|
459
|
+
<< std::setfill('0') << std::setw(2) << (chunk.size() > 7 ? (unsigned)(uint8_t)chunk[7] : 0));
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
return buffer;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
std::vector<uint8_t> EncryptedSocket::frame_message(const std::vector<uint8_t>& message) {
|
|
467
|
+
std::vector<uint8_t> framed(MESSAGE_HEADER_SIZE + message.size());
|
|
468
|
+
|
|
469
|
+
// Add magic number (convert to network byte order)
|
|
470
|
+
uint32_t magic_be = htonl(NOISE_MESSAGE_MAGIC);
|
|
471
|
+
std::memcpy(framed.data(), &magic_be, 4);
|
|
472
|
+
|
|
473
|
+
// Add message length (convert to network byte order)
|
|
474
|
+
uint32_t length = static_cast<uint32_t>(message.size());
|
|
475
|
+
uint32_t length_be = htonl(length);
|
|
476
|
+
std::memcpy(framed.data() + 4, &length_be, 4);
|
|
477
|
+
|
|
478
|
+
// Add message data
|
|
479
|
+
std::memcpy(framed.data() + MESSAGE_HEADER_SIZE, message.data(), message.size());
|
|
480
|
+
|
|
481
|
+
return framed;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
std::vector<uint8_t> EncryptedSocket::unframe_message(const std::vector<uint8_t>& framed_message) {
|
|
485
|
+
if (framed_message.size() < MESSAGE_HEADER_SIZE) {
|
|
486
|
+
return {};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// Check magic number (convert from network byte order)
|
|
490
|
+
uint32_t magic;
|
|
491
|
+
std::memcpy(&magic, framed_message.data(), 4);
|
|
492
|
+
magic = ntohl(magic);
|
|
493
|
+
if (magic != NOISE_MESSAGE_MAGIC) {
|
|
494
|
+
return {};
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// Get message length (convert from network byte order)
|
|
498
|
+
uint32_t length;
|
|
499
|
+
std::memcpy(&length, framed_message.data() + 4, 4);
|
|
500
|
+
length = ntohl(length);
|
|
501
|
+
|
|
502
|
+
if (length > NOISE_MAX_MESSAGE_SIZE || framed_message.size() < MESSAGE_HEADER_SIZE + length) {
|
|
503
|
+
return {};
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Extract message
|
|
507
|
+
std::vector<uint8_t> message(length);
|
|
508
|
+
std::memcpy(message.data(), framed_message.data() + MESSAGE_HEADER_SIZE, length);
|
|
509
|
+
|
|
510
|
+
return message;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
bool EncryptedSocket::is_noise_handshake_message(const std::vector<uint8_t>& data) {
|
|
514
|
+
if (data.size() < 4) {
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
uint32_t magic;
|
|
519
|
+
std::memcpy(&magic, data.data(), 4);
|
|
520
|
+
magic = ntohl(magic); // Convert from network byte order
|
|
521
|
+
return magic == HANDSHAKE_MESSAGE_MAGIC;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
//=============================================================================
|
|
525
|
+
// EncryptedSocketManager Implementation
|
|
526
|
+
//=============================================================================
|
|
527
|
+
|
|
528
|
+
EncryptedSocketManager::EncryptedSocketManager() : encryption_enabled_(true) {
|
|
529
|
+
// Generate a default static key
|
|
530
|
+
static_key_ = noise_utils::generate_static_keypair();
|
|
531
|
+
LOG_ENCRYPT_INFO("Generated default static key for encrypted socket manager");
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
EncryptedSocketManager::~EncryptedSocketManager() {
|
|
535
|
+
cleanup_all_sockets();
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
EncryptedSocketManager& EncryptedSocketManager::getInstance() {
|
|
539
|
+
static EncryptedSocketManager instance;
|
|
540
|
+
return instance;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
bool EncryptedSocketManager::initialize_socket_as_initiator(socket_t socket, const NoiseKey& static_private_key) {
|
|
544
|
+
return encrypted_socket_.initialize_as_initiator(socket, static_private_key);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
bool EncryptedSocketManager::initialize_socket_as_responder(socket_t socket, const NoiseKey& static_private_key) {
|
|
548
|
+
return encrypted_socket_.initialize_as_responder(socket, static_private_key);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
bool EncryptedSocketManager::send_data(socket_t socket, const std::vector<uint8_t>& data) {
|
|
552
|
+
if (!encryption_enabled_) {
|
|
553
|
+
return encrypted_socket_.send_unencrypted_data(socket, data);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if (encrypted_socket_.is_handshake_completed(socket)) {
|
|
557
|
+
return encrypted_socket_.send_encrypted_data(socket, data);
|
|
558
|
+
} else {
|
|
559
|
+
LOG_ENCRYPT_WARN("Attempting to send binary data on socket " << socket << " before handshake completion");
|
|
560
|
+
return false;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
bool EncryptedSocketManager::send_data(socket_t socket, const std::string& data) {
|
|
565
|
+
// Convert string to binary and use primary binary method
|
|
566
|
+
std::vector<uint8_t> binary_data(data.begin(), data.end());
|
|
567
|
+
return send_data(socket, binary_data);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
std::vector<uint8_t> EncryptedSocketManager::receive_data(socket_t socket) {
|
|
571
|
+
if (!encryption_enabled_) {
|
|
572
|
+
return encrypted_socket_.receive_unencrypted_data(socket);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
if (encrypted_socket_.is_handshake_completed(socket)) {
|
|
576
|
+
return encrypted_socket_.receive_encrypted_data(socket);
|
|
577
|
+
} else {
|
|
578
|
+
LOG_ENCRYPT_WARN("Attempting to receive binary data on socket " << socket << " before handshake completion");
|
|
579
|
+
return std::vector<uint8_t>();
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
std::string EncryptedSocketManager::receive_data_string(socket_t socket) {
|
|
584
|
+
// Use primary binary method and convert to string
|
|
585
|
+
std::vector<uint8_t> binary_data = receive_data(socket);
|
|
586
|
+
if (binary_data.empty()) {
|
|
587
|
+
return "";
|
|
588
|
+
}
|
|
589
|
+
return std::string(binary_data.begin(), binary_data.end());
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
bool EncryptedSocketManager::perform_handshake_step(socket_t socket, const std::vector<uint8_t>& received_data) {
|
|
593
|
+
LOG_ENCRYPT_DEBUG("perform_handshake_step called for socket " << socket << " with " << received_data.size() << " bytes of received data");
|
|
594
|
+
|
|
595
|
+
if (!encryption_enabled_) {
|
|
596
|
+
LOG_ENCRYPT_DEBUG("Encryption not enabled, returning true");
|
|
597
|
+
return true; // No handshake needed when encryption is disabled
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
if (encrypted_socket_.is_handshake_completed(socket)) {
|
|
601
|
+
LOG_ENCRYPT_DEBUG("Handshake already completed for socket " << socket);
|
|
602
|
+
return true; // Already completed
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
if (encrypted_socket_.has_handshake_failed(socket)) {
|
|
606
|
+
LOG_ENCRYPT_DEBUG("Handshake already failed for socket " << socket);
|
|
607
|
+
return false; // Already failed
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
try {
|
|
611
|
+
NoiseRole role = encrypted_socket_.get_socket_role(socket);
|
|
612
|
+
|
|
613
|
+
if (received_data.empty()) {
|
|
614
|
+
// For initiators, only send the initial handshake message if we haven't started yet
|
|
615
|
+
if (role == NoiseRole::INITIATOR) {
|
|
616
|
+
auto* session = encrypted_socket_.get_session(socket);
|
|
617
|
+
if (session && session->session->get_handshake_state() == NoiseHandshakeState::WRITE_MESSAGE_1) {
|
|
618
|
+
LOG_ENCRYPT_DEBUG("Initiator sending initial handshake message on socket " << socket);
|
|
619
|
+
return encrypted_socket_.send_handshake_message(socket);
|
|
620
|
+
} else {
|
|
621
|
+
LOG_ENCRYPT_DEBUG("Initiator waiting for responder message (state: " << static_cast<int>(session ? session->session->get_handshake_state() : NoiseHandshakeState::FAILED) << ")");
|
|
622
|
+
// Initiator should wait for responder's message, not keep sending
|
|
623
|
+
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
624
|
+
return !encrypted_socket_.has_handshake_failed(socket);
|
|
625
|
+
}
|
|
626
|
+
} else {
|
|
627
|
+
// For responders, try to receive and process incoming handshake data
|
|
628
|
+
auto* session = encrypted_socket_.get_session(socket);
|
|
629
|
+
if (session && session->session->get_handshake_state() == NoiseHandshakeState::READ_MESSAGE_1) {
|
|
630
|
+
LOG_ENCRYPT_DEBUG("Responder trying to receive first handshake message on socket " << socket);
|
|
631
|
+
auto payload = encrypted_socket_.receive_handshake_message(socket);
|
|
632
|
+
|
|
633
|
+
// If we received a handshake message, we need to send a response
|
|
634
|
+
if (!payload.empty()) {
|
|
635
|
+
LOG_ENCRYPT_DEBUG("Responder received handshake message (" << payload.size() << " bytes) on socket " << socket);
|
|
636
|
+
if (!encrypted_socket_.is_handshake_completed(socket)) {
|
|
637
|
+
LOG_ENCRYPT_DEBUG("Responder sending handshake response on socket " << socket);
|
|
638
|
+
return encrypted_socket_.send_handshake_message(socket);
|
|
639
|
+
}
|
|
640
|
+
} else {
|
|
641
|
+
LOG_ENCRYPT_DEBUG("Responder received empty handshake message on socket " << socket);
|
|
642
|
+
if (encrypted_socket_.has_handshake_failed(socket)) {
|
|
643
|
+
LOG_ENCRYPT_DEBUG("Handshake failed for socket " << socket);
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
} else {
|
|
648
|
+
LOG_ENCRYPT_DEBUG("Responder waiting for initiator or already processed initial message (state: " << static_cast<int>(session ? session->session->get_handshake_state() : NoiseHandshakeState::FAILED) << ")");
|
|
649
|
+
// Responder should wait for the next message or handshake completion
|
|
650
|
+
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
return !encrypted_socket_.has_handshake_failed(socket);
|
|
654
|
+
}
|
|
655
|
+
} else {
|
|
656
|
+
// Process received handshake message
|
|
657
|
+
auto payload = encrypted_socket_.receive_handshake_message(socket);
|
|
658
|
+
|
|
659
|
+
// If we received a handshake message and we're the responder,
|
|
660
|
+
// we might need to send a response
|
|
661
|
+
if (!encrypted_socket_.is_handshake_completed(socket)) {
|
|
662
|
+
if (role == NoiseRole::RESPONDER) {
|
|
663
|
+
return encrypted_socket_.send_handshake_message(socket);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return !encrypted_socket_.has_handshake_failed(socket);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
} catch (const std::exception& e) {
|
|
671
|
+
LOG_ENCRYPT_ERROR("Exception in perform_handshake_step: " << e.what());
|
|
672
|
+
return false;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
bool EncryptedSocketManager::is_handshake_completed(socket_t socket) const {
|
|
677
|
+
if (!encryption_enabled_) {
|
|
678
|
+
return true; // No handshake needed when encryption is disabled
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
return encrypted_socket_.is_handshake_completed(socket);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
bool EncryptedSocketManager::has_handshake_failed(socket_t socket) const {
|
|
685
|
+
if (!encryption_enabled_) {
|
|
686
|
+
return false; // No handshake to fail when encryption is disabled
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
return encrypted_socket_.has_handshake_failed(socket);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
void EncryptedSocketManager::remove_socket(socket_t socket) {
|
|
693
|
+
encrypted_socket_.remove_socket(socket);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
void EncryptedSocketManager::cleanup_all_sockets() {
|
|
697
|
+
encrypted_socket_.clear_all_sockets();
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
//=============================================================================
|
|
701
|
+
// High-level encrypted communication functions
|
|
702
|
+
//=============================================================================
|
|
703
|
+
|
|
704
|
+
namespace encrypted_communication {
|
|
705
|
+
|
|
706
|
+
bool initialize_encryption(const NoiseKey& static_key) {
|
|
707
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
708
|
+
manager.set_static_key(static_key);
|
|
709
|
+
manager.set_encryption_enabled(true);
|
|
710
|
+
|
|
711
|
+
LOG_ENCRYPT_INFO("Initialized encryption with provided static key");
|
|
712
|
+
return true;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
NoiseKey generate_node_key() {
|
|
716
|
+
NoiseKey key = EncryptedSocket::generate_static_key();
|
|
717
|
+
LOG_ENCRYPT_INFO("Generated new node static key: " << EncryptedSocket::key_to_string(key));
|
|
718
|
+
return key;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
void set_encryption_enabled(bool enabled) {
|
|
722
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
723
|
+
manager.set_encryption_enabled(enabled);
|
|
724
|
+
|
|
725
|
+
LOG_ENCRYPT_INFO("Encryption " << (enabled ? "enabled" : "disabled"));
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
bool is_encryption_enabled() {
|
|
729
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
730
|
+
return manager.is_encryption_enabled();
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
int send_tcp_data_encrypted(socket_t socket, const std::vector<uint8_t>& data) {
|
|
734
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
735
|
+
|
|
736
|
+
if (manager.send_data(socket, data)) {
|
|
737
|
+
return static_cast<int>(data.size());
|
|
738
|
+
}
|
|
739
|
+
return -1;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
int send_tcp_data_encrypted(socket_t socket, const std::string& data) {
|
|
743
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
744
|
+
|
|
745
|
+
if (manager.send_data(socket, data)) {
|
|
746
|
+
return static_cast<int>(data.size());
|
|
747
|
+
}
|
|
748
|
+
return -1;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
std::vector<uint8_t> receive_tcp_data_encrypted(socket_t socket, size_t buffer_size) {
|
|
752
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
753
|
+
return manager.receive_data(socket);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
std::string receive_tcp_data_encrypted_string(socket_t socket, size_t buffer_size) {
|
|
757
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
758
|
+
return manager.receive_data_string(socket);
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
bool initialize_outgoing_connection(socket_t socket) {
|
|
762
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
763
|
+
|
|
764
|
+
if (!manager.is_encryption_enabled()) {
|
|
765
|
+
return true; // No initialization needed when encryption is disabled
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
bool success = manager.initialize_socket_as_initiator(socket, manager.get_static_key());
|
|
769
|
+
if (success) {
|
|
770
|
+
LOG_ENCRYPT_INFO("Initialized outgoing encrypted connection for socket " << socket);
|
|
771
|
+
|
|
772
|
+
// Perform initial handshake step
|
|
773
|
+
success = manager.perform_handshake_step(socket);
|
|
774
|
+
if (!success) {
|
|
775
|
+
LOG_ENCRYPT_ERROR("Failed initial handshake step for outgoing connection on socket " << socket);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
return success;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
bool initialize_incoming_connection(socket_t socket) {
|
|
783
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
784
|
+
|
|
785
|
+
if (!manager.is_encryption_enabled()) {
|
|
786
|
+
return true; // No initialization needed when encryption is disabled
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
bool success = manager.initialize_socket_as_responder(socket, manager.get_static_key());
|
|
790
|
+
if (success) {
|
|
791
|
+
LOG_ENCRYPT_INFO("Initialized incoming encrypted connection for socket " << socket);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
return success;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
bool perform_handshake(socket_t socket) {
|
|
798
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
799
|
+
LOG_ENCRYPT_DEBUG("perform_handshake called for socket " << socket);
|
|
800
|
+
bool result = manager.perform_handshake_step(socket);
|
|
801
|
+
LOG_ENCRYPT_DEBUG("perform_handshake_step returned " << result << " for socket " << socket);
|
|
802
|
+
return result;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
bool is_handshake_completed(socket_t socket) {
|
|
806
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
807
|
+
return manager.is_handshake_completed(socket);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
void cleanup_socket(socket_t socket) {
|
|
811
|
+
auto& manager = EncryptedSocketManager::getInstance();
|
|
812
|
+
manager.remove_socket(socket);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
} // namespace encrypted_communication
|
|
816
|
+
|
|
817
|
+
} // namespace librats
|