Move RSA class to Crypt
This commit is contained in:
parent
fa15c25951
commit
fb7ab21e71
|
@ -1,4 +1,4 @@
|
|||
local currentRsa = OTSERV_RSA
|
||||
local currentRsa
|
||||
|
||||
function g_game.getRsa()
|
||||
return currentRsa
|
||||
|
@ -6,14 +6,17 @@ end
|
|||
|
||||
function g_game.chooseRsa(host)
|
||||
if host:match('.*\.tibia\.com') or host:match('.*\.cipsoft\.com') then
|
||||
currentRsa = CIPSOFT_RSA
|
||||
g_game.setRsa(CIPSOFT_RSA)
|
||||
else
|
||||
currentRsa = OTSERV_RSA
|
||||
g_game.setRsa(OTSERV_RSA)
|
||||
end
|
||||
end
|
||||
|
||||
function g_game.setRsa(rsa)
|
||||
if currentRsa ~= rsa then
|
||||
currentRsa = rsa
|
||||
g_crypt.rsaSetPublicKey(currentRsa, '65537')
|
||||
end
|
||||
end
|
||||
|
||||
function g_game.isOfficialTibia()
|
||||
|
@ -45,3 +48,4 @@ function g_game.getSupportedProtocols()
|
|||
}
|
||||
end
|
||||
|
||||
g_game.setRsa(OTSERV_RSA)
|
||||
|
|
|
@ -65,7 +65,7 @@ function ProtocolLogin:sendLoginPacket()
|
|||
end
|
||||
|
||||
msg:addPaddingBytes(paddingBytes, 0)
|
||||
msg:encryptRsa(128, g_game.getRsa())
|
||||
msg:encryptRsa(128)
|
||||
|
||||
self:send(msg)
|
||||
self:enableXteaEncryption()
|
||||
|
|
|
@ -29,8 +29,6 @@ set(framework_SOURCES ${framework_SOURCES}
|
|||
${CMAKE_CURRENT_LIST_DIR}/util/matrix.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/util/point.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/util/rect.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/util/rsa.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/util/rsa.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/util/size.h
|
||||
|
||||
# stdext
|
||||
|
|
|
@ -83,10 +83,13 @@ void Application::registerLuaFunctions()
|
|||
|
||||
// Crypt
|
||||
g_lua.registerSingletonClass("g_crypt");
|
||||
g_lua.bindClassStaticFunction("g_crypt", "encrypt", Crypt::encrypt);
|
||||
g_lua.bindClassStaticFunction("g_crypt", "decrypt", Crypt::decrypt);
|
||||
g_lua.bindClassStaticFunction("g_crypt", "sha1Encode", Crypt::sha1Encode);
|
||||
g_lua.bindClassStaticFunction("g_crypt", "md5Encode", Crypt::md5Encode);
|
||||
g_lua.bindSingletonFunction("g_crypt", "encrypt", &Crypt::encrypt, &g_crypt);
|
||||
g_lua.bindSingletonFunction("g_crypt", "decrypt", &Crypt::decrypt, &g_crypt);
|
||||
g_lua.bindSingletonFunction("g_crypt", "sha1Encode", &Crypt::sha1Encode, &g_crypt);
|
||||
g_lua.bindSingletonFunction("g_crypt", "md5Encode", &Crypt::md5Encode, &g_crypt);
|
||||
g_lua.bindSingletonFunction("g_crypt", "rsaSetPublicKey", &Crypt::rsaSetPublicKey, &g_crypt);
|
||||
g_lua.bindSingletonFunction("g_crypt", "rsaSetPrivateKey", &Crypt::rsaSetPrivateKey, &g_crypt);
|
||||
g_lua.bindSingletonFunction("g_crypt", "rsaCheckKey", &Crypt::rsaCheckKey, &g_crypt);
|
||||
|
||||
// Clock
|
||||
g_lua.registerSingletonClass("g_clock");
|
||||
|
@ -635,6 +638,8 @@ void Application::registerLuaFunctions()
|
|||
// Server
|
||||
g_lua.registerClass<Server>();
|
||||
g_lua.bindClassStaticFunction<Server>("create", &Server::create);
|
||||
g_lua.bindClassMemberFunction<Server>("close", &Server::close);
|
||||
g_lua.bindClassMemberFunction<Server>("isOpen", &Server::isOpen);
|
||||
g_lua.bindClassMemberFunction<Server>("acceptNext", &Server::acceptNext);
|
||||
|
||||
// Connection
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "inputmessage.h"
|
||||
#include <framework/util/rsa.h>
|
||||
#include <framework/util/crypt.h>
|
||||
|
||||
InputMessage::InputMessage()
|
||||
{
|
||||
|
@ -86,13 +86,10 @@ std::string InputMessage::getString()
|
|||
return std::string(v, stringLength);
|
||||
}
|
||||
|
||||
bool InputMessage::decryptRsa(int size, const std::string& key, const std::string& p, const std::string& q, const std::string& d)
|
||||
bool InputMessage::decryptRsa(int size)
|
||||
{
|
||||
checkRead(size);
|
||||
g_rsa.setPublic(key.c_str(), "65537");
|
||||
g_rsa.setPrivate(p.c_str(), q.c_str(), d.c_str());
|
||||
g_rsa.check();
|
||||
g_rsa.decrypt((unsigned char*)m_buffer + m_readPos, size);
|
||||
g_crypt.rsaDecrypt((unsigned char*)m_buffer + m_readPos, size);
|
||||
return (getU8() == 0x00);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
uint32 peekU32() { uint32 v = getU32(); m_readPos-=4; return v; }
|
||||
uint64 peekU64() { uint64 v = getU64(); m_readPos-=8; return v; }
|
||||
|
||||
bool decryptRsa(int size, const std::string& key, const std::string& p, const std::string& q, const std::string& d);
|
||||
bool decryptRsa(int size);
|
||||
|
||||
int getReadSize() { return m_readPos - m_headerPos; }
|
||||
int getReadPos() { return m_readPos; }
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
|
||||
#include <framework/net/outputmessage.h>
|
||||
#include <framework/util/rsa.h>
|
||||
#include <framework/util/crypt.h>
|
||||
|
||||
OutputMessage::OutputMessage()
|
||||
{
|
||||
|
@ -89,13 +89,12 @@ void OutputMessage::addPaddingBytes(int bytes, uint8 byte)
|
|||
m_messageSize += bytes;
|
||||
}
|
||||
|
||||
void OutputMessage::encryptRsa(int size, const std::string& key)
|
||||
void OutputMessage::encryptRsa(int size)
|
||||
{
|
||||
if(m_messageSize < size)
|
||||
throw stdext::exception("insufficient bytes in buffer to encrypt");
|
||||
|
||||
g_rsa.setPublic(key.c_str(), "65537");
|
||||
g_rsa.encrypt((unsigned char*)m_buffer + m_writePos - size, size);
|
||||
g_crypt.rsaEncrypt((unsigned char*)m_buffer + m_writePos - size, size);
|
||||
}
|
||||
|
||||
void OutputMessage::writeChecksum()
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
void addString(const std::string& buffer);
|
||||
void addPaddingBytes(int bytes, uint8 byte = 0);
|
||||
|
||||
void encryptRsa(int size, const std::string& key);
|
||||
void encryptRsa(int size);
|
||||
|
||||
uint16 getMessageSize() { return m_messageSize; }
|
||||
|
||||
|
|
|
@ -35,15 +35,23 @@ ServerPtr Server::create(int port)
|
|||
return ServerPtr(new Server(port));
|
||||
}
|
||||
|
||||
void Server::close()
|
||||
{
|
||||
m_isOpen = false;
|
||||
m_acceptor.cancel();
|
||||
m_acceptor.close();
|
||||
}
|
||||
|
||||
void Server::acceptNext()
|
||||
{
|
||||
ConnectionPtr connection = ConnectionPtr(new Connection);
|
||||
connection->m_connecting = true;
|
||||
auto self = static_self_cast<Server>();
|
||||
m_acceptor.async_accept(connection->m_socket, [=](const boost::system::error_code& error) {
|
||||
if(!error) {
|
||||
connection->m_connected = true;
|
||||
connection->m_connecting = false;
|
||||
}
|
||||
callLuaField("onAccept", connection, error.message(), error.value());
|
||||
self->callLuaField("onAccept", connection, error.message(), error.value());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -28,15 +28,16 @@
|
|||
|
||||
class Server : public LuaObject
|
||||
{
|
||||
typedef std::function<void(ConnectionPtr, const boost::system::error_code&)> AcceptCallback;
|
||||
|
||||
public:
|
||||
Server(int port);
|
||||
static ServerPtr create(int port);
|
||||
bool isOpen() { return m_isOpen; }
|
||||
void close();
|
||||
|
||||
void acceptNext();
|
||||
|
||||
private:
|
||||
stdext::boolean<true> m_isOpen;
|
||||
asio::ip::tcp::acceptor m_acceptor;
|
||||
};
|
||||
|
||||
|
|
|
@ -22,16 +22,31 @@
|
|||
|
||||
#include "crypt.h"
|
||||
#include <framework/stdext/math.h>
|
||||
#include <framework/core/logger.h>
|
||||
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static inline bool is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); }
|
||||
|
||||
Crypt g_crypt;
|
||||
|
||||
Crypt::Crypt()
|
||||
{
|
||||
m_rsa = RSA_new();
|
||||
}
|
||||
|
||||
Crypt::~Crypt()
|
||||
{
|
||||
RSA_free(m_rsa);
|
||||
}
|
||||
|
||||
std::string Crypt::base64Encode(const std::string& decoded_string)
|
||||
{
|
||||
std::string ret;
|
||||
|
@ -204,3 +219,49 @@ std::string Crypt::sha1Encode(std::string decoded_string, bool upperCase)
|
|||
std::transform(result.begin(), result.end(), result.begin(), tolower);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Crypt::rsaSetPublicKey(const std::string& n, const std::string& e)
|
||||
{
|
||||
BN_dec2bn(&m_rsa->n, n.c_str());
|
||||
BN_dec2bn(&m_rsa->e, e.c_str());
|
||||
}
|
||||
|
||||
void Crypt::rsaSetPrivateKey(const std::string& p, const std::string& q, const std::string& d)
|
||||
{
|
||||
BN_dec2bn(&m_rsa->p, p.c_str());
|
||||
BN_dec2bn(&m_rsa->q, q.c_str());
|
||||
BN_dec2bn(&m_rsa->d, d.c_str());
|
||||
}
|
||||
|
||||
bool Crypt::rsaCheckKey()
|
||||
{
|
||||
// only used by server, that sets both public and private
|
||||
if(RSA_check_key(m_rsa)) {
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
BIGNUM *r1 = BN_CTX_get(ctx), *r2 = BN_CTX_get(ctx);
|
||||
BN_mod(m_rsa->dmp1, m_rsa->d, r1, ctx);
|
||||
BN_mod(m_rsa->dmq1, m_rsa->d, r2, ctx);
|
||||
|
||||
BN_mod_inverse(m_rsa->iqmp, m_rsa->q, m_rsa->p, ctx);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
ERR_load_crypto_strings();
|
||||
g_logger.error(stdext::format("RSA check failed - %s", ERR_error_string(ERR_get_error(), NULL)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Crypt::rsaEncrypt(unsigned char *msg, int size)
|
||||
{
|
||||
assert(size <= 128);
|
||||
return RSA_public_encrypt(size, msg, msg, m_rsa, RSA_NO_PADDING) != -1;
|
||||
}
|
||||
|
||||
bool Crypt::rsaDecrypt(unsigned char *msg, int size)
|
||||
{
|
||||
assert(size <= 128);
|
||||
return RSA_private_decrypt(size, msg, msg, m_rsa, RSA_NO_PADDING) != -1;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,14 @@
|
|||
#include "../stdext/types.h"
|
||||
#include <string>
|
||||
|
||||
namespace Crypt {
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
class Crypt
|
||||
{
|
||||
public:
|
||||
Crypt();
|
||||
~Crypt();
|
||||
|
||||
std::string base64Encode(const std::string& decoded_string);
|
||||
std::string base64Decode(const std::string& encoded_string);
|
||||
std::string xorCrypt(const std::string& buffer, const std::string& key);
|
||||
|
@ -35,6 +42,17 @@ namespace Crypt {
|
|||
std::string decrypt(const std::string& encrypted_string);
|
||||
std::string md5Encode(std::string decoded_string, bool upperCase);
|
||||
std::string sha1Encode(std::string decoded_string, bool upperCase);
|
||||
}
|
||||
|
||||
void rsaSetPublicKey(const std::string& n, const std::string& e);
|
||||
void rsaSetPrivateKey(const std::string &p, const std::string &q, const std::string &d);
|
||||
bool rsaCheckKey();
|
||||
bool rsaEncrypt(unsigned char *msg, int size);
|
||||
bool rsaDecrypt(unsigned char *msg, int size);
|
||||
|
||||
private:
|
||||
RSA *m_rsa;
|
||||
};
|
||||
|
||||
extern Crypt g_crypt;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "rsa.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
Rsa g_rsa;
|
||||
|
||||
Rsa::Rsa()
|
||||
{
|
||||
m_rsa = RSA_new();
|
||||
}
|
||||
|
||||
Rsa::~Rsa()
|
||||
{
|
||||
RSA_free(m_rsa);
|
||||
}
|
||||
|
||||
void Rsa::setPublic(const char *n, const char *e)
|
||||
{
|
||||
BN_dec2bn(&m_rsa->n, n);
|
||||
BN_dec2bn(&m_rsa->e, e);
|
||||
}
|
||||
|
||||
void Rsa::setPrivate(const char *p, const char *q, const char *d)
|
||||
{
|
||||
BN_dec2bn(&m_rsa->p, p);
|
||||
BN_dec2bn(&m_rsa->q, q);
|
||||
BN_dec2bn(&m_rsa->d, d);
|
||||
}
|
||||
|
||||
bool Rsa::check() // only used by server, that sets both public and private
|
||||
{
|
||||
if(RSA_check_key(m_rsa)) {
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
BIGNUM *r1 = BN_CTX_get(ctx), *r2 = BN_CTX_get(ctx);
|
||||
BN_mod(m_rsa->dmp1, m_rsa->d, r1, ctx);
|
||||
BN_mod(m_rsa->dmq1, m_rsa->d, r2, ctx);
|
||||
|
||||
BN_mod_inverse(m_rsa->iqmp, m_rsa->q, m_rsa->p, ctx);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
ERR_load_crypto_strings();
|
||||
g_logger.error(stdext::format("RSA check failed - %s", ERR_error_string(ERR_get_error(), NULL)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Rsa::encrypt(unsigned char *msg, int size)
|
||||
{
|
||||
assert(size <= 128);
|
||||
return RSA_public_encrypt(size, msg, msg, m_rsa, RSA_NO_PADDING) != -1;
|
||||
}
|
||||
|
||||
bool Rsa::decrypt(unsigned char *msg, int size)
|
||||
{
|
||||
assert(size <= 128);
|
||||
return RSA_private_decrypt(size, msg, msg, m_rsa, RSA_NO_PADDING) != -1;
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef RSA_H
|
||||
#define RSA_H
|
||||
|
||||
#include <framework/global.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
class Rsa
|
||||
{
|
||||
public:
|
||||
Rsa();
|
||||
~Rsa();
|
||||
|
||||
void setPublic(const char *n, const char *e);
|
||||
void setPrivate(const char *p, const char *q, const char *d);
|
||||
bool check();
|
||||
|
||||
bool encrypt(unsigned char *msg, int size);
|
||||
bool decrypt(unsigned char *msg, int size);
|
||||
|
||||
private:
|
||||
RSA *m_rsa;
|
||||
};
|
||||
|
||||
extern Rsa g_rsa;
|
||||
|
||||
#endif
|
|
@ -91,7 +91,7 @@ void ProtocolGame::sendLoginPacket(uint challangeTimestamp, uint8 challangeRando
|
|||
msg->addPaddingBytes(paddingBytes);
|
||||
|
||||
// encrypt with RSA
|
||||
msg->encryptRsa(128, g_lua.callGlobalField<std::string>("g_game", "getRsa"));
|
||||
msg->encryptRsa(128);
|
||||
|
||||
send(msg);
|
||||
|
||||
|
|
Loading…
Reference in New Issue