mirror of
https://github.com/HikikoMarmy/Champions-Reborn-Server.git
synced 2026-04-05 08:59:54 -03:00
Change Misc to Common and cleanups.
This commit is contained in:
449
Common/ByteStream.cpp
Normal file
449
Common/ByteStream.cpp
Normal file
@@ -0,0 +1,449 @@
|
||||
#include <codecvt>
|
||||
#include "ByteStream.h"
|
||||
#include <span>
|
||||
|
||||
ByteBuffer::ByteBuffer( const std::vector< uint8_t > &data )
|
||||
{
|
||||
this->m_buffer = data;
|
||||
this->m_position = 0;
|
||||
}
|
||||
|
||||
ByteBuffer::ByteBuffer( const std::string &data )
|
||||
{
|
||||
this->m_buffer = std::vector< uint8_t >( data.begin(), data.end() );
|
||||
this->m_position = 0;
|
||||
}
|
||||
|
||||
ByteBuffer::ByteBuffer( const uint8_t *data, uint32_t length )
|
||||
{
|
||||
this->m_buffer = std::vector< uint8_t >( data, data + length );
|
||||
this->m_position = 0;
|
||||
}
|
||||
|
||||
ByteBuffer::ByteBuffer( uint32_t length )
|
||||
{
|
||||
this->m_buffer = std::vector< uint8_t >( length, 0 );
|
||||
this->m_position = 0;
|
||||
}
|
||||
|
||||
ByteBuffer::ByteBuffer()
|
||||
{
|
||||
this->m_position = 0;
|
||||
}
|
||||
|
||||
ByteBuffer::~ByteBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void ByteBuffer::resize( uint32_t size )
|
||||
{
|
||||
m_buffer.resize( size );
|
||||
}
|
||||
|
||||
void ByteBuffer::shrink_to_fit()
|
||||
{
|
||||
m_buffer.shrink_to_fit();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void ByteBuffer::write( T value )
|
||||
{
|
||||
write_bytes( ( uint8_t * )&value, sizeof( T ) );
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
T ByteBuffer::read()
|
||||
{
|
||||
if( m_position >= m_buffer.size() )
|
||||
{
|
||||
return (T)0;
|
||||
}
|
||||
|
||||
T value = *( T * )&m_buffer[ m_position ];
|
||||
m_position += sizeof( T );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void ByteBuffer::write_utf8( const std::string &str, std::optional<uint32_t> length )
|
||||
{
|
||||
if( length.has_value() )
|
||||
{
|
||||
write_u32( length.value() );
|
||||
|
||||
if( length.value() > str.size() )
|
||||
{
|
||||
write_bytes( std::vector< uint8_t >( str.begin(), str.end() ) );
|
||||
write_bytes( std::vector< uint8_t >( length.value() - str.size(), 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
write_bytes( std::vector< uint8_t >( str.begin(), str.begin() + length.value() ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
write_u32( static_cast< uint32_t >( str.size() ) );
|
||||
write_bytes( std::vector< uint8_t >( str.begin(), str.end() ) );
|
||||
}
|
||||
}
|
||||
|
||||
void ByteBuffer::write_utf16( const std::wstring &str, std::optional<uint32_t> length )
|
||||
{
|
||||
write_u32( static_cast< uint32_t >( str.size() ) );
|
||||
|
||||
for( wchar_t ch : str )
|
||||
{
|
||||
uint16_t val = static_cast< uint16_t >( ch );
|
||||
write<uint8_t>( val & 0xFF );
|
||||
write<uint8_t>( ( val >> 8 ) & 0xFF );
|
||||
}
|
||||
}
|
||||
|
||||
void ByteBuffer::write_sz_utf8( const std::string &str, std::optional<uint32_t> length )
|
||||
{
|
||||
if( length )
|
||||
{
|
||||
write_bytes( std::vector< uint8_t >( str.begin(), str.end() ) );
|
||||
write_bytes( std::vector< uint8_t >( length.value() - str.size(), 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
write_bytes( std::vector< uint8_t >( str.begin(), str.end() ) );
|
||||
write< uint8_t >( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void ByteBuffer::write_sz_utf16( const std::wstring &str, std::optional<uint32_t> length )
|
||||
{
|
||||
for( wchar_t ch : str )
|
||||
{
|
||||
uint16_t val = static_cast< uint16_t >( ch );
|
||||
write<uint8_t>( val & 0xFF );
|
||||
write<uint8_t>( ( val >> 8 ) & 0xFF );
|
||||
}
|
||||
|
||||
if( length )
|
||||
{
|
||||
size_t bytesWritten = str.size() * 2;
|
||||
size_t totalBytes = length.value();
|
||||
|
||||
if( bytesWritten < totalBytes )
|
||||
{
|
||||
write_bytes( std::vector<uint8_t>( totalBytes - bytesWritten, 0 ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
write<uint16_t>( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void ByteBuffer::write_encrypted_utf8( const std::string &str )
|
||||
{
|
||||
auto encrypted = RealmCrypt::encryptSymmetric( std::vector< uint8_t >( str.begin(), str.end() ) );
|
||||
|
||||
write_u32( static_cast< uint32_t >( encrypted.size() ) + 4 );
|
||||
write_u32( static_cast< uint32_t >( str.size() ) );
|
||||
|
||||
write_bytes( encrypted );
|
||||
}
|
||||
|
||||
void ByteBuffer::write_encrypted_utf16( const std::wstring &str )
|
||||
{
|
||||
std::vector< uint8_t > utf16;
|
||||
for( auto c : str )
|
||||
{
|
||||
utf16.push_back( c & 0xFF );
|
||||
utf16.push_back( ( c >> 8 ) & 0xFF );
|
||||
}
|
||||
|
||||
auto encrypted = RealmCrypt::encryptSymmetric( utf16 );
|
||||
uint32_t encryptedLength = static_cast< uint32_t >( encrypted.size() );
|
||||
uint32_t decryptedLength = static_cast< uint32_t >( utf16.size() );
|
||||
|
||||
// Correct blockLength: in 2-byte words, including the 4-byte decrypted length
|
||||
write_u32( ( encryptedLength + 4 ) / 2 );
|
||||
write_u32( decryptedLength );
|
||||
|
||||
write_bytes( encrypted );
|
||||
}
|
||||
|
||||
uint8_t ByteBuffer::read_u8()
|
||||
{
|
||||
return read< uint8_t >();
|
||||
}
|
||||
|
||||
uint16_t ByteBuffer::read_u16()
|
||||
{
|
||||
return read< uint16_t >();
|
||||
}
|
||||
|
||||
uint32_t ByteBuffer::read_u32()
|
||||
{
|
||||
return read< uint32_t >();
|
||||
}
|
||||
|
||||
int8_t ByteBuffer::read_i8()
|
||||
{
|
||||
return read< int8_t >();
|
||||
}
|
||||
|
||||
int16_t ByteBuffer::read_i16()
|
||||
{
|
||||
return read< int16_t >();
|
||||
}
|
||||
|
||||
int32_t ByteBuffer::read_i32()
|
||||
{
|
||||
return read< int32_t >();
|
||||
}
|
||||
|
||||
float_t ByteBuffer::read_f32()
|
||||
{
|
||||
return read< float_t >();
|
||||
}
|
||||
|
||||
std::string ByteBuffer::read_utf8( std::optional<uint32_t> length )
|
||||
{
|
||||
if( !length )
|
||||
{
|
||||
length = read_u32();
|
||||
}
|
||||
|
||||
if( m_position + length.value() > m_buffer.size() )
|
||||
{
|
||||
throw std::runtime_error( "read_utf8: Attempt to read past end of buffer" );
|
||||
}
|
||||
|
||||
std::string value( reinterpret_cast< const char * >( &m_buffer[ m_position ] ), length.value() );
|
||||
m_position += length.value();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::wstring ByteBuffer::read_utf16( std::optional<uint32_t> length )
|
||||
{
|
||||
if( !length )
|
||||
{
|
||||
length = read_u32();
|
||||
}
|
||||
|
||||
uint32_t byteLength = length.value() * 2;
|
||||
|
||||
if( m_position + byteLength > m_buffer.size() )
|
||||
{
|
||||
throw std::runtime_error( "read_utf16: Attempt to read past end of buffer" );
|
||||
}
|
||||
|
||||
std::wstring value;
|
||||
value.reserve( length.value() );
|
||||
|
||||
for( size_t i = 0; i < byteLength; i += 2 )
|
||||
{
|
||||
uint16_t ch = m_buffer[ m_position + i ] | ( m_buffer[ m_position + i + 1 ] << 8 );
|
||||
value.push_back( static_cast< wchar_t >( ch ) );
|
||||
}
|
||||
|
||||
m_position += byteLength;
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string ByteBuffer::read_sz_utf8()
|
||||
{
|
||||
std::string value;
|
||||
while( m_buffer[ m_position ] != 0 )
|
||||
{
|
||||
value.push_back( m_buffer[ m_position ] );
|
||||
m_position++;
|
||||
}
|
||||
|
||||
m_position++;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::wstring ByteBuffer::read_sz_utf16()
|
||||
{
|
||||
std::wstring value;
|
||||
while( m_buffer[ m_position ] != 0 || m_buffer[ m_position + 1 ] != 0 )
|
||||
{
|
||||
value.push_back( m_buffer[ m_position ] | ( m_buffer[ m_position + 1 ] << 8 ) );
|
||||
m_position += 2;
|
||||
}
|
||||
|
||||
m_position += 2;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string ByteBuffer::read_encrypted_utf8( bool hasBlockLength )
|
||||
{
|
||||
uint32_t encryptedLength = 0;
|
||||
uint32_t decryptedLength = 0;
|
||||
|
||||
if( hasBlockLength )
|
||||
{
|
||||
uint32_t blockLength = read_u32() * 2;
|
||||
decryptedLength = read_u32();
|
||||
encryptedLength = blockLength - 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
decryptedLength = read_u32();
|
||||
encryptedLength = Util::round_up( decryptedLength, 16 );
|
||||
}
|
||||
|
||||
std::span< const uint8_t > encryptedBuffer( m_buffer.data() + m_position, encryptedLength );
|
||||
|
||||
m_position += encryptedLength;
|
||||
|
||||
if( decryptedLength == 0 )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Decrypt the buffer
|
||||
std::vector< uint8_t > decryptedBuffer = RealmCrypt::decryptSymmetric( encryptedBuffer );
|
||||
|
||||
std::string result( decryptedBuffer.begin(), decryptedBuffer.end() );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring ByteBuffer::read_encrypted_utf16( bool hasBlockLength )
|
||||
{
|
||||
uint32_t encryptedLength = 0;
|
||||
uint32_t decryptedLength = 0;
|
||||
|
||||
if( hasBlockLength )
|
||||
{
|
||||
uint32_t blockLength = read_u32() * 2;
|
||||
decryptedLength = read_u32(); // This length is already multiplied by sizeof(wchar_t)
|
||||
encryptedLength = blockLength - 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
decryptedLength = read_u32();
|
||||
encryptedLength = Util::round_up( decryptedLength, 16 );
|
||||
}
|
||||
|
||||
std::span< const uint8_t > encryptedBuffer( m_buffer.data() + m_position, encryptedLength );
|
||||
|
||||
m_position += encryptedLength;
|
||||
|
||||
if( decryptedLength == 0 )
|
||||
{
|
||||
return L"";
|
||||
}
|
||||
|
||||
// Decrypt the buffer
|
||||
std::vector< uint8_t > decryptedBuffer = RealmCrypt::decryptSymmetric( encryptedBuffer );
|
||||
|
||||
std::wstring result( decryptedLength / 2, L'\0' );
|
||||
std::memcpy( result.data(), decryptedBuffer.data(), decryptedLength );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ByteBuffer::write_bytes( const std::vector< uint8_t > &value )
|
||||
{
|
||||
std::copy( value.begin(), value.end(), std::back_inserter( m_buffer ) );
|
||||
m_position += value.size();
|
||||
}
|
||||
|
||||
void ByteBuffer::write_bytes( const uint8_t *value, uint32_t length )
|
||||
{
|
||||
std::copy( value, value + length, std::back_inserter( m_buffer ) );
|
||||
m_position += length;
|
||||
}
|
||||
|
||||
void ByteBuffer::write_encrypted_bytes( const std::vector<uint8_t> &value )
|
||||
{
|
||||
auto encrypted = RealmCrypt::encryptSymmetric( value );
|
||||
|
||||
write_u32( static_cast< uint32_t >( encrypted.size() ) + 4 );
|
||||
write_u32( static_cast< uint32_t >( value.size() ) );
|
||||
|
||||
write_bytes( encrypted );
|
||||
}
|
||||
|
||||
std::vector<uint8_t> ByteBuffer::read_bytes( uint32_t length )
|
||||
{
|
||||
std::vector<uint8_t> value( length, 0 );
|
||||
|
||||
std::copy( m_buffer.begin() + m_position, m_buffer.begin() + m_position + length, value.begin() );
|
||||
|
||||
m_position += length;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> ByteBuffer::read_encrypted_bytes( uint32_t length )
|
||||
{
|
||||
std::vector< uint8_t > encrypted = read_bytes( length );
|
||||
|
||||
auto decrypted = RealmCrypt::decryptSymmetric( encrypted );
|
||||
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> ByteBuffer::get_buffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
size_t ByteBuffer::get_length() const
|
||||
{
|
||||
return m_buffer.size();
|
||||
}
|
||||
|
||||
void ByteBuffer::set_position( size_t where )
|
||||
{
|
||||
if( where > m_buffer.size() )
|
||||
{
|
||||
where = m_buffer.size();
|
||||
}
|
||||
|
||||
this->m_position = where;
|
||||
}
|
||||
|
||||
size_t ByteBuffer::get_position() const
|
||||
{
|
||||
return this->m_position;
|
||||
}
|
||||
|
||||
void ByteBuffer::write_u8( uint8_t value )
|
||||
{
|
||||
write< uint8_t >( value );
|
||||
}
|
||||
|
||||
void ByteBuffer::write_u16( uint16_t value )
|
||||
{
|
||||
write< uint16_t >( value );
|
||||
}
|
||||
|
||||
void ByteBuffer::write_u32( uint32_t value )
|
||||
{
|
||||
write< uint32_t >( value );
|
||||
}
|
||||
|
||||
void ByteBuffer::write_i8( int8_t value )
|
||||
{
|
||||
write< int8_t >( value );
|
||||
}
|
||||
|
||||
void ByteBuffer::write_i16( int16_t value )
|
||||
{
|
||||
write< int16_t >( value );
|
||||
}
|
||||
|
||||
void ByteBuffer::write_i32( int32_t value )
|
||||
{
|
||||
write< int32_t >( value );
|
||||
}
|
||||
|
||||
void ByteBuffer::write_f32( float_t value )
|
||||
{
|
||||
write< float_t >( value );
|
||||
}
|
||||
85
Common/ByteStream.h
Normal file
85
Common/ByteStream.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
|
||||
#include "Utility.h"
|
||||
#include "../Crypto/RealmCrypt.h"
|
||||
|
||||
class ByteBuffer {
|
||||
public:
|
||||
ByteBuffer( const std::vector< uint8_t > &data );
|
||||
ByteBuffer( const std::string &data );
|
||||
ByteBuffer( const uint8_t *data, uint32_t length );
|
||||
ByteBuffer( uint32_t length );
|
||||
ByteBuffer();
|
||||
|
||||
~ByteBuffer();
|
||||
|
||||
void resize( uint32_t size );
|
||||
void shrink_to_fit();
|
||||
|
||||
template < typename T >
|
||||
void write( T value );
|
||||
|
||||
template < typename T >
|
||||
T read();
|
||||
|
||||
void forward( uint32_t length ) {
|
||||
m_position += length;
|
||||
if ( m_position > m_buffer.size() ) {
|
||||
m_position = m_buffer.size();
|
||||
}
|
||||
}
|
||||
|
||||
void write_u8( uint8_t value );
|
||||
void write_u16( uint16_t value );
|
||||
void write_u32( uint32_t value );
|
||||
void write_i8( int8_t value );
|
||||
void write_i16( int16_t value );
|
||||
void write_i32( int32_t value );
|
||||
void write_f32( float_t value );
|
||||
|
||||
void write_utf8( const std::string &str, std::optional<uint32_t> length = std::nullopt );
|
||||
void write_utf16( const std::wstring &str, std::optional<uint32_t> length = std::nullopt );
|
||||
void write_sz_utf8( const std::string &str, std::optional<uint32_t> length = std::nullopt );
|
||||
void write_sz_utf16( const std::wstring &str, std::optional<uint32_t> length = std::nullopt );
|
||||
void write_encrypted_utf8( const std::string &str );
|
||||
void write_encrypted_utf16( const std::wstring &str );
|
||||
|
||||
uint8_t read_u8();
|
||||
uint16_t read_u16();
|
||||
uint32_t read_u32();
|
||||
int8_t read_i8();
|
||||
int16_t read_i16();
|
||||
int32_t read_i32();
|
||||
float_t read_f32();
|
||||
|
||||
std::string read_utf8( std::optional<uint32_t> length = std::nullopt );
|
||||
std::wstring read_utf16( std::optional<uint32_t> length = std::nullopt );
|
||||
std::string read_sz_utf8();
|
||||
std::wstring read_sz_utf16();
|
||||
std::string read_encrypted_utf8( bool hasBlockLength = true );
|
||||
std::wstring read_encrypted_utf16( bool hasBlockLength = true );
|
||||
|
||||
void write_bytes( const std::vector< uint8_t > &value );
|
||||
void write_bytes( const uint8_t *value, uint32_t length );
|
||||
void write_encrypted_bytes( const std::vector< uint8_t > &value );
|
||||
|
||||
std::vector< uint8_t > read_bytes( uint32_t length );
|
||||
std::vector< uint8_t > read_encrypted_bytes( uint32_t length );
|
||||
|
||||
std::vector< uint8_t > get_buffer() const;
|
||||
|
||||
size_t get_length() const;
|
||||
size_t get_position() const;
|
||||
void set_position( size_t where );
|
||||
|
||||
std::vector< uint8_t > m_buffer;
|
||||
size_t m_position;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr< ByteBuffer > sptr_byte_stream;
|
||||
9
Common/Constant.h
Normal file
9
Common/Constant.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
constexpr int32_t MAX_SESSION_ID_LENGTH = 16;
|
||||
constexpr int32_t MAX_NUMBER_OF_CHARACTERS = 12;
|
||||
|
||||
enum RealmGameType {
|
||||
CHAMPIONS_OF_NORRATH = 0,
|
||||
RETURN_TO_ARMS = 1,
|
||||
};
|
||||
83
Common/Utility.cpp
Normal file
83
Common/Utility.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
#include "Utility.h"
|
||||
|
||||
int32_t Util::round_up( int32_t numToRound, int32_t multiple )
|
||||
{
|
||||
if( multiple == 0 )
|
||||
return numToRound;
|
||||
|
||||
int32_t remainder = abs( numToRound ) % multiple;
|
||||
if( remainder == 0 )
|
||||
return numToRound;
|
||||
|
||||
if( numToRound < 0 )
|
||||
return -( abs( numToRound ) - remainder );
|
||||
else
|
||||
return numToRound + multiple - remainder;
|
||||
}
|
||||
|
||||
int32_t Util::round_down( int32_t numToRound, int32_t multiple )
|
||||
{
|
||||
if( multiple == 0 )
|
||||
return numToRound;
|
||||
|
||||
int32_t remainder = abs( numToRound ) % multiple;
|
||||
if( remainder == 0 )
|
||||
return numToRound;
|
||||
|
||||
if( numToRound < 0 )
|
||||
return -( abs( numToRound ) + remainder );
|
||||
else
|
||||
return numToRound - remainder;
|
||||
}
|
||||
|
||||
uint16_t Util::ByteSwap( uint16_t val )
|
||||
{
|
||||
return ( val << 8 ) | ( val >> 8 );
|
||||
}
|
||||
|
||||
uint32_t Util::ByteSwap( uint32_t val )
|
||||
{
|
||||
return ( ( val << 24 ) & 0xFF000000 ) |
|
||||
( ( val << 8 ) & 0x00FF0000 ) |
|
||||
( ( val >> 8 ) & 0x0000FF00 ) |
|
||||
( ( val >> 24 ) & 0x000000FF );
|
||||
}
|
||||
|
||||
std::string Util::WideToUTF8( const std::wstring &wstr )
|
||||
{
|
||||
if( wstr.empty() ) return {};
|
||||
|
||||
int size_needed = WideCharToMultiByte(
|
||||
CP_UTF8, 0, wstr.c_str(), static_cast< int >( wstr.size() ),
|
||||
nullptr, 0, nullptr, nullptr
|
||||
);
|
||||
|
||||
std::string result( size_needed, 0 );
|
||||
|
||||
WideCharToMultiByte(
|
||||
CP_UTF8, 0, wstr.c_str(), static_cast< int >( wstr.size() ),
|
||||
&result[ 0 ], size_needed, nullptr, nullptr
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring Util::UTF8ToWide( const std::string &str )
|
||||
{
|
||||
if( str.empty() ) return {};
|
||||
int size_needed = MultiByteToWideChar(
|
||||
CP_UTF8, 0, str.c_str(), static_cast< int >( str.size() ),
|
||||
nullptr, 0
|
||||
);
|
||||
std::wstring result( size_needed, 0 );
|
||||
MultiByteToWideChar(
|
||||
CP_UTF8, 0, str.c_str(), static_cast< int >( str.size() ),
|
||||
&result[ 0 ], size_needed
|
||||
);
|
||||
return result;
|
||||
}
|
||||
22
Common/Utility.h
Normal file
22
Common/Utility.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace Util
|
||||
{
|
||||
int32_t round_up( int32_t numToRound, int32_t multiple );
|
||||
int32_t round_down( int32_t numToRound, int32_t multiple );
|
||||
|
||||
uint16_t ByteSwap( uint16_t val );
|
||||
uint32_t ByteSwap( uint32_t val );
|
||||
|
||||
template <typename T>
|
||||
bool IsInRange( T value, T min, T max )
|
||||
{
|
||||
return ( value >= min && value <= max );
|
||||
}
|
||||
|
||||
std::string WideToUTF8( const std::wstring &wstr );
|
||||
std::wstring UTF8ToWide( const std::string &str );
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
#include "RealmCrypt.h"
|
||||
#include "../misc/Utility.h"
|
||||
#include "../Common/Utility.h"
|
||||
|
||||
RealmCrypt::RealmCrypt()
|
||||
{
|
||||
@@ -63,40 +63,63 @@ std::string RealmCrypt::decryptString( std::string &input )
|
||||
return std::string( reinterpret_cast< const char * >( result ), input.size() );
|
||||
}
|
||||
|
||||
std::wstring RealmCrypt::encryptString( std::wstring &input )
|
||||
std::vector<uint8_t> RealmCrypt::encryptString( const std::wstring &input )
|
||||
{
|
||||
if( input.size() % 16 != 0 )
|
||||
// Convert UTF-16 string to raw bytes
|
||||
std::vector<uint8_t> utf16Bytes;
|
||||
utf16Bytes.reserve( input.size() * 2 );
|
||||
for( wchar_t ch : input )
|
||||
{
|
||||
input.append( 16 - ( input.size() % 16 ), L'\0' );
|
||||
utf16Bytes.push_back( static_cast< uint8_t >( ch & 0xFF ) );
|
||||
utf16Bytes.push_back( static_cast< uint8_t >( ( ch >> 8 ) & 0xFF ) );
|
||||
}
|
||||
|
||||
rijndael aes;
|
||||
// Pad to nearest 16 bytes
|
||||
if( utf16Bytes.size() % 16 != 0 )
|
||||
{
|
||||
utf16Bytes.resize( ( utf16Bytes.size() / 16 + 1 ) * 16, 0 );
|
||||
}
|
||||
|
||||
auto result = aes.EncryptECB( reinterpret_cast< const uint8_t * >(
|
||||
input.c_str() ),
|
||||
static_cast< uint32_t >( input.size() ),
|
||||
// Encrypt using AES ECB
|
||||
rijndael aes;
|
||||
auto encrypted = aes.EncryptECB(
|
||||
reinterpret_cast< const uint8_t * >( utf16Bytes.data() ),
|
||||
static_cast< uint32_t >( utf16Bytes.size() ),
|
||||
default_sym_key.data()
|
||||
);
|
||||
|
||||
return std::wstring( reinterpret_cast< const wchar_t * >( result ), input.size() );
|
||||
// Return the raw encrypted bytes
|
||||
return std::vector<uint8_t>( encrypted, encrypted + utf16Bytes.size() );
|
||||
}
|
||||
|
||||
std::wstring RealmCrypt::decryptString( std::wstring &input )
|
||||
std::wstring RealmCrypt::decryptString( std::vector<uint8_t> &input )
|
||||
{
|
||||
// Ensure input is a multiple of 16 bytes
|
||||
if( input.size() % 16 != 0 )
|
||||
{
|
||||
input.append( 16 - ( input.size() % 16 ), L'\0' );
|
||||
input.resize( ( input.size() / 16 + 1 ) * 16, 0 );
|
||||
}
|
||||
|
||||
rijndael aes;
|
||||
|
||||
auto result = aes.DecryptECB( reinterpret_cast< const uint8_t * >(
|
||||
input.c_str() ),
|
||||
auto result = aes.DecryptECB(
|
||||
reinterpret_cast< const uint8_t * >( input.data() ),
|
||||
static_cast< uint32_t >( input.size() ),
|
||||
default_sym_key.data()
|
||||
);
|
||||
|
||||
return std::wstring( reinterpret_cast< const wchar_t * >( result ), input.size() );
|
||||
// Convert decrypted bytes back into a wstring
|
||||
std::wstring output;
|
||||
output.reserve( input.size() / 2 );
|
||||
|
||||
for( size_t i = 0; i + 1 < input.size(); i += 2 )
|
||||
{
|
||||
uint16_t ch = static_cast< uint16_t >( input[ i ] | ( input[ i + 1 ] << 8 ) );
|
||||
if( ch == 0 ) break; // Optional: stop at null terminator
|
||||
output.push_back( static_cast< wchar_t >( ch ) );
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
std::vector< uint8_t > RealmCrypt::encryptSymmetric( std::span< const uint8_t > input )
|
||||
|
||||
@@ -34,8 +34,8 @@ public:
|
||||
// Encrypt and decrypt strings.
|
||||
static std::string encryptString( std::string &input );
|
||||
static std::string decryptString( std::string &input );
|
||||
static std::wstring encryptString( std::wstring &input );
|
||||
static std::wstring decryptString( std::wstring &input );
|
||||
static std::vector<uint8_t> encryptString( const std::wstring &input );
|
||||
static std::wstring decryptString( std::vector<uint8_t> &input );
|
||||
|
||||
// Encrypt and decrypt byte arrays.
|
||||
static std::vector< uint8_t > encryptSymmetric( std::span< const uint8_t > input );
|
||||
|
||||
Reference in New Issue
Block a user