172 const bool Authentifier::JoinServer(
const std::string& server_id,
const std::vector<unsigned char>& shared_secret,
const std::vector<unsigned char>& public_key)
const
174#ifndef USE_ENCRYPTION
179 LOG_ERROR(
"Trying to join a server before authentication");
184 SHA1_Init(&sha_context);
186 SHA1_Update(&sha_context, server_id.c_str(), server_id.length());
187 SHA1_Update(&sha_context, shared_secret.data(), shared_secret.size());
190 std::vector<unsigned char> digest(SHA_DIGEST_LENGTH);
191 SHA1_Final(digest.data(), &sha_context);
195 bool is_negative = digest[0] & (1 << 7);
201 for (
int i = 0; i < digest.size(); ++i)
203 digest[i] = ~digest[i];
207 int position =
static_cast<int>(digest.size()) - 1;
208 while (digest[position] == 255 && position > 0)
210 digest[position] = 0;
213 digest[position] += 1;
217 std::stringstream ss;
218 for (
int i = 0; i < digest.size(); ++i)
220 ss << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(digest[i] & 0xFF);
223 std::string server_hash = ss.str();
225 const size_t start = server_hash.find_first_not_of(
'0');
226 if (start != std::string::npos)
228 server_hash = server_hash.substr(start);
237 server_hash =
"-" + server_hash;
244 {
"serverId", server_hash}
248 "application/json; charset=utf-8",
"*/*",
"", data.
Dump());
253 <<
" (" << post_response.
status_message <<
") during server join:\n"
302 const int message_sent_index,
const UUID& chat_session_uuid,
303 const std::vector<std::vector<unsigned char>>& last_seen,
304 long long int& salt,
long long int& timestamp)
307#ifndef USE_ENCRYPTION
308 LOG_ERROR(
"Trying to compute message signature while botcraft was compiled without USE_ENCRYPTION.");
311 if (mc_player_uuid.empty() || private_key.empty())
313 LOG_ERROR(
"Trying to join a server before authentication");
318 salt = std::uniform_int_distribution<long long int>(std::numeric_limits<long long int>::min(), std::numeric_limits<long long int>::max())(rnd);
319 timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
320 std::array<unsigned char, 8> salt_bytes;
321 std::array<unsigned char, 8> timestamp_bytes;
323 for (
int i = 0; i < 8; ++i)
325 salt_bytes[i] =
static_cast<unsigned char>((salt >> (8 * (7 - i))) & 0xFF);
327 timestamp_bytes[i] =
static_cast<unsigned char>(((timestamp / 1000) >> (8 * (7 - i))) & 0xFF);
330 std::array<unsigned char, SHA256_DIGEST_LENGTH> signature_hash;
331#if PROTOCOL_VERSION == 759
333 const std::string jsoned_message =
"{\"text\":\"" + message +
"\"}";
337 SHA256_Init(&sha256);
338 SHA256_Update(&sha256, salt_bytes.data(), salt_bytes.size());
339 SHA256_Update(&sha256, mc_player_uuid_bytes.data(), mc_player_uuid_bytes.size());
340 SHA256_Update(&sha256, timestamp_bytes.data(), timestamp_bytes.size());
341 SHA256_Update(&sha256, jsoned_message.data(), jsoned_message.size());
342#elif PROTOCOL_VERSION == 760
343 const unsigned char const_byte_70 = 70;
346 std::array<unsigned char, SHA256_DIGEST_LENGTH> body_hash;
347 SHA256_CTX body_sha256;
348 SHA256_Init(&body_sha256);
349 SHA256_Update(&body_sha256, salt_bytes.data(), salt_bytes.size());
350 SHA256_Update(&body_sha256, timestamp_bytes.data(), timestamp_bytes.size());
351 SHA256_Update(&body_sha256, message.data(), message.size());
352 SHA256_Update(&body_sha256, &const_byte_70, 1);
354 for (
int i = 0; i < last_seen.size(); ++i)
356 SHA256_Update(&body_sha256, &const_byte_70, 1);
357 SHA256_Update(&body_sha256, last_seen[i].GetProfileId().data(), last_seen[i].GetProfileId().size());
358 SHA256_Update(&body_sha256, last_seen[i].GetLastSignature().data(), last_seen[i].GetLastSignature().size());
360 SHA256_Final(body_hash.data(), &body_sha256);
365 SHA256_Init(&sha256);
366 if (!previous_signature.empty())
368 SHA256_Update(&sha256, previous_signature.data(), previous_signature.size());
370 SHA256_Update(&sha256, mc_player_uuid_bytes.data(), mc_player_uuid_bytes.size());
371 SHA256_Update(&sha256, body_hash.data(), body_hash.size());
373 std::array<unsigned char, 4> bytes_1_big_endian;
374 std::array<unsigned char, 4> message_sent_index_bytes;
375 std::array<unsigned char, 4> message_size_bytes;
376 std::array<unsigned char, 4> last_seen_size_bytes;
378 for (
int i = 0; i < 4; ++i)
380 bytes_1_big_endian[i] =
static_cast<unsigned char>((1 >> (8 * (3 - i))) & 0xFF);
381 message_sent_index_bytes[i] =
static_cast<unsigned char>((message_sent_index >> (8 * (3 - i))) & 0xFF);
382 message_size_bytes[i] =
static_cast<unsigned char>((
static_cast<int>(message.size()) >> (8 * (3 - i))) & 0xFF);
383 last_seen_size_bytes[i] =
static_cast<unsigned char>((
static_cast<int>(last_seen.size()) >> (8 * (3 - i))) & 0xFF);
388 SHA256_Init(&sha256);
389 SHA256_Init(&sha256);
391 SHA256_Update(&sha256, bytes_1_big_endian.data(), bytes_1_big_endian.size());
393 SHA256_Update(&sha256, mc_player_uuid_bytes.data(), mc_player_uuid_bytes.size());
394 SHA256_Update(&sha256, chat_session_uuid.data(), chat_session_uuid.size());
395 SHA256_Update(&sha256, message_sent_index_bytes.data(), message_sent_index_bytes.size());
397 SHA256_Update(&sha256, salt_bytes.data(), salt_bytes.size());
398 SHA256_Update(&sha256, timestamp_bytes.data(), timestamp_bytes.size());
399 SHA256_Update(&sha256, message_size_bytes.data(), message_size_bytes.size());
400 SHA256_Update(&sha256, message.data(), message.size());
401 SHA256_Update(&sha256, last_seen_size_bytes.data(), last_seen_size_bytes.size());
402 for (
size_t i = 0; i < last_seen.size(); ++i)
404 SHA256_Update(&sha256, last_seen[i].data(), last_seen[i].size());
407 SHA256_Final(signature_hash.data(), &sha256);
412 RSA* rsa_signature =
nullptr;
413 const char* c_string = private_key.c_str();
414 BIO* keybio = BIO_new_mem_buf((
void*)c_string, -1);
415 rsa_signature = PEM_read_bio_RSAPrivateKey(keybio, &rsa_signature, NULL, NULL);
419 const int rsa_signature_size = RSA_size(rsa_signature);
420 std::vector<unsigned char> signature(rsa_signature_size);
421 unsigned int signature_size;
422 RSA_sign(NID_sha256, signature_hash.data(),
static_cast<unsigned int>(signature_hash.size()), signature.data(), &signature_size, rsa_signature);
423 RSA_free(rsa_signature);
424 signature.resize(signature_size);
1174 asio::io_context io_context;
1177 asio::ip::tcp::resolver resolver(io_context);
1178 asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(host,
"https");
1180 asio::ssl::context ctx(asio::ssl::context::sslv23);
1181 ctx.set_default_verify_paths();
1182 ctx.set_options(asio::ssl::context::default_workarounds | asio::ssl::context::verify_none);
1184 asio::ssl::stream<asio::ip::tcp::socket> socket(io_context, ctx);
1185 socket.set_verify_mode(asio::ssl::verify_none);
1186 socket.set_verify_callback([](
bool, asio::ssl::verify_context&) {
return true; });
1187 SSL_set_tlsext_host_name(socket.native_handle(), host.c_str());
1188 asio::connect(socket.lowest_layer(), endpoints);
1189 socket.handshake(socket.client);
1190 socket.lowest_layer().set_option(asio::ip::tcp::no_delay(
true));
1193 asio::streambuf request;
1194 std::ostream request_stream(&request);
1195 request_stream << raw_request;
1197 asio::write(socket, request);
1204 asio::streambuf response;
1205 asio::read_until(socket, response,
"\r\n");
1208 std::istream response_stream(&response);
1209 std::string http_version;
1210 response_stream >> http_version;
1218 if (!response_stream || http_version.substr(0, 5) !=
"HTTP/")
1220 LOG_ERROR(
"Invalid response during web request");
1222 return web_response;
1229 return web_response;
1233 asio::read_until(socket, response,
"\r\n\r\n");
1237 long long int data_length = -1;
1238 while (std::getline(response_stream, header) && header !=
"\r")
1240 if (header.find(
"Content-Length: ") == 0)
1242 data_length = std::stoll(header.substr(16));
1247 std::stringstream output_stringstream;
1248 if (response.size() > 0)
1250 output_stringstream << &response;
1254 asio::error_code error;
1255 while (asio::read(socket, response, asio::transfer_at_least(1), error))
1257 output_stringstream << &response;
1259 const std::string raw_response = output_stringstream.str();
1261 if (error != asio::error::eof && raw_response.size() != data_length)
1263 LOG_ERROR(
"Error trying to read web request response, Error:\n " << error);
1271 return web_response;