eq2go/old/common/crypto.hpp
2025-08-06 19:00:30 -05:00

135 lines
2.5 KiB
C++

// Copyright (C) 2007 EQ2EMulator Development Team, GPL v3 License
#pragma once
#include <string>
#include <mutex>
#include <cstring>
#include <iostream>
#include "rc4.hpp"
#include "types.hpp"
#include "packet/packet_dump.hpp"
using namespace std;
/**
* Crypto class handles RSA decryption and RC4 encryption/decryption operations
* for secure client-server communication in the EQ2 emulator
*/
class Crypto
{
public:
/**
* Default constructor - initializes crypto state to unencrypted
*/
Crypto()
{
rc4_key = 0;
encrypted = false;
client = nullptr;
server = nullptr;
}
/**
* Destructor - cleans up RC4 cipher instances
*/
~Crypto()
{
safe_delete(client);
safe_delete(server);
}
/**
* Decrypts RSA-encrypted data by reversing byte order and converting to int64
*/
static int64 RSADecrypt(uchar* text, int16 size)
{
int64 ret = 0;
uchar* buffer = new uchar[8];
// Reverse byte order for proper endianness
for (int i = 7; i >= 0; i--) {
buffer[7 - i] = text[i];
}
memcpy(&ret, buffer, 8);
safe_delete_array(buffer);
return ret;
}
/**
* Encrypts data using RC4 server cipher with thread safety
*/
void RC4Encrypt(uchar* text, int32 size)
{
MCrypto.lock();
server->Cypher(text, size);
MCrypto.unlock();
}
/**
* Decrypts data using RC4 client cipher with thread safety
*/
void RC4Decrypt(uchar* text, int32 size)
{
MCrypto.lock();
client->Cypher(text, size);
MCrypto.unlock();
}
/**
* Gets the current RC4 encryption key
*/
int64 getRC4Key()
{
return rc4_key;
}
/**
* Sets the RC4 encryption key and initializes cipher instances
*/
void setRC4Key(int64 key)
{
rc4_key = key;
if (key > 0) {
encrypted = true;
client = new RC4(~key); // Client uses inverted key
server = new RC4(key); // Server uses original key
// Initialize cipher states with dummy data
uchar temp[20];
client->Cypher(temp, 20);
server->Cypher(temp, 20);
}
else {
encrypted = false;
safe_delete(client);
safe_delete(server);
}
}
/**
* Checks if encryption is currently enabled
*/
bool isEncrypted()
{
return encrypted;
}
/**
* Manually sets the encryption state
*/
void setEncrypted(bool in_val)
{
encrypted = in_val;
}
private:
RC4* server; // Server-side RC4 cipher instance
RC4* client; // Client-side RC4 cipher instance
bool encrypted; // Current encryption state flag
int64 rc4_key; // RC4 encryption key value
mutex MCrypto; // Mutex for thread-safe cipher operations
};