POW optimization and general cleanup
This commit is contained in:
parent
4cb3e04c88
commit
3c703e6db4
@ -6,7 +6,8 @@ namespace Components
|
|||||||
Auth::TokenIncrementing Auth::TokenContainer;
|
Auth::TokenIncrementing Auth::TokenContainer;
|
||||||
|
|
||||||
Utils::Cryptography::Token Auth::GuidToken;
|
Utils::Cryptography::Token Auth::GuidToken;
|
||||||
Utils::Cryptography::ECDSA::Key Auth::GuidKey;
|
Utils::Cryptography::Token Auth::ComputeToken;
|
||||||
|
Utils::Cryptography::ECC::Key Auth::GuidKey;
|
||||||
|
|
||||||
void Auth::Frame()
|
void Auth::Frame()
|
||||||
{
|
{
|
||||||
@ -146,7 +147,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Auth::LoadKey();
|
Auth::LoadKey();
|
||||||
std::string key = Auth::GuidKey.GetPublicKey();
|
std::string key = Auth::GuidKey.GetPublicKey();
|
||||||
return (Utils::OneAtATime(key.data(), key.size()));
|
return (Utils::Cryptography::JenkinsOneAtATime::Compute(key.data(), key.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Auth::StoreKey()
|
void Auth::StoreKey()
|
||||||
@ -155,6 +156,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Proto::Auth::Certificate cert;
|
Proto::Auth::Certificate cert;
|
||||||
cert.set_token(Auth::GuidToken.ToString());
|
cert.set_token(Auth::GuidToken.ToString());
|
||||||
|
cert.set_ctoken(Auth::ComputeToken.ToString());
|
||||||
cert.set_privatekey(Auth::GuidKey.Export(PK_PRIVATE));
|
cert.set_privatekey(Auth::GuidKey.Export(PK_PRIVATE));
|
||||||
|
|
||||||
Utils::WriteFile("players/guid.dat", cert.SerializeAsString());
|
Utils::WriteFile("players/guid.dat", cert.SerializeAsString());
|
||||||
@ -171,6 +173,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Auth::GuidKey.Import(cert.privatekey(), PK_PRIVATE);
|
Auth::GuidKey.Import(cert.privatekey(), PK_PRIVATE);
|
||||||
Auth::GuidToken = cert.token();
|
Auth::GuidToken = cert.token();
|
||||||
|
Auth::ComputeToken = cert.ctoken();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -180,7 +183,8 @@ namespace Components
|
|||||||
if (!Auth::GuidKey.IsValid())
|
if (!Auth::GuidKey.IsValid())
|
||||||
{
|
{
|
||||||
Auth::GuidToken.Clear();
|
Auth::GuidToken.Clear();
|
||||||
Auth::GuidKey = Utils::Cryptography::ECDSA::GenerateKey(512);
|
Auth::ComputeToken.Clear();
|
||||||
|
Auth::GuidKey = Utils::Cryptography::ECC::GenerateKey(512);
|
||||||
Auth::StoreKey();
|
Auth::StoreKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,7 +213,7 @@ namespace Components
|
|||||||
Auth::TokenContainer.generating = true;
|
Auth::TokenContainer.generating = true;
|
||||||
Auth::TokenContainer.hashes = 0;
|
Auth::TokenContainer.hashes = 0;
|
||||||
Auth::TokenContainer.startTime = Game::Com_Milliseconds();
|
Auth::TokenContainer.startTime = Game::Com_Milliseconds();
|
||||||
Auth::IncrementToken(Auth::GuidToken, Auth::GuidKey.GetPublicKey(), Auth::TokenContainer.targetLevel, &Auth::TokenContainer.cancel, &Auth::TokenContainer.hashes);
|
Auth::IncrementToken(Auth::GuidToken, Auth::ComputeToken, Auth::GuidKey.GetPublicKey(), Auth::TokenContainer.targetLevel, &Auth::TokenContainer.cancel, &Auth::TokenContainer.hashes);
|
||||||
Auth::TokenContainer.generating = false;
|
Auth::TokenContainer.generating = false;
|
||||||
|
|
||||||
if (Auth::TokenContainer.cancel)
|
if (Auth::TokenContainer.cancel)
|
||||||
@ -250,27 +254,30 @@ namespace Components
|
|||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Auth::IncrementToken(Utils::Cryptography::Token& token, std::string publicKey, uint32_t zeroBits, bool* cancel, uint64_t* count)
|
void Auth::IncrementToken(Utils::Cryptography::Token& token, Utils::Cryptography::Token& computeToken, std::string publicKey, uint32_t zeroBits, bool* cancel, uint64_t* count)
|
||||||
{
|
{
|
||||||
if (zeroBits > 512) return; // Not possible, due to SHA512
|
if (zeroBits > 512) return; // Not possible, due to SHA512
|
||||||
|
|
||||||
Utils::Cryptography::Token tempToken(token);
|
if (computeToken < token)
|
||||||
|
{
|
||||||
|
computeToken = token;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if we already have the desired security level
|
// Check if we already have the desired security level
|
||||||
uint32_t lastLevel = Auth::GetZeroBits(tempToken, publicKey);
|
uint32_t lastLevel = Auth::GetZeroBits(token, publicKey);
|
||||||
uint32_t level = lastLevel;
|
uint32_t level = lastLevel;
|
||||||
if (level >= zeroBits) return;
|
if (level >= zeroBits) return;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
++tempToken;
|
++computeToken;
|
||||||
if (count) ++(*count);
|
if (count) ++(*count);
|
||||||
level = Auth::GetZeroBits(tempToken, publicKey);
|
level = Auth::GetZeroBits(computeToken, publicKey);
|
||||||
|
|
||||||
// Store level if higher than the last one
|
// Store level if higher than the last one
|
||||||
if (level >= lastLevel)
|
if (level >= lastLevel)
|
||||||
{
|
{
|
||||||
token = tempToken;
|
token = computeToken;
|
||||||
lastLevel = level;
|
lastLevel = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +286,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
while (level < zeroBits);
|
while (level < zeroBits);
|
||||||
|
|
||||||
token = tempToken;
|
token = computeToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
Auth::Auth()
|
Auth::Auth()
|
||||||
@ -309,7 +316,7 @@ namespace Components
|
|||||||
Proto::Auth::Response response;
|
Proto::Auth::Response response;
|
||||||
response.set_token(Auth::GuidToken.ToString());
|
response.set_token(Auth::GuidToken.ToString());
|
||||||
response.set_publickey(Auth::GuidKey.GetPublicKey());
|
response.set_publickey(Auth::GuidKey.GetPublicKey());
|
||||||
response.set_signature(Utils::Cryptography::ECDSA::SignMessage(Auth::GuidKey, data));
|
response.set_signature(Utils::Cryptography::ECC::SignMessage(Auth::GuidKey, data));
|
||||||
|
|
||||||
Network::SendCommand(address, "xuidAuthResp", response.SerializeAsString());
|
Network::SendCommand(address, "xuidAuthResp", response.SerializeAsString());
|
||||||
});
|
});
|
||||||
@ -337,7 +344,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if guid matches the certificate
|
// Check if guid matches the certificate
|
||||||
else if (id != (Utils::OneAtATime(response.publickey().data(), response.publickey().size()) & ~0x80000000))
|
else if (id != (Utils::Cryptography::JenkinsOneAtATime::Compute(response.publickey().data(), response.publickey().size()) & ~0x80000000))
|
||||||
{
|
{
|
||||||
info->state = Auth::STATE_INVALID;
|
info->state = Auth::STATE_INVALID;
|
||||||
Game::SV_KickClientError(client, "XUID doesn't match the certificate!");
|
Game::SV_KickClientError(client, "XUID doesn't match the certificate!");
|
||||||
@ -348,7 +355,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
info->publicKey.Set(response.publickey());
|
info->publicKey.Set(response.publickey());
|
||||||
|
|
||||||
if (Utils::Cryptography::ECDSA::VerifyMessage(info->publicKey, info->challenge, response.signature()))
|
if (Utils::Cryptography::ECC::VerifyMessage(info->publicKey, info->challenge, response.signature()))
|
||||||
{
|
{
|
||||||
uint32_t ourLevel = static_cast<uint32_t>(Dvar::Var("sv_securityLevel").Get<int>());
|
uint32_t ourLevel = static_cast<uint32_t>(Dvar::Var("sv_securityLevel").Get<int>());
|
||||||
uint32_t userLevel = Auth::GetZeroBits(response.token(), response.publickey());
|
uint32_t userLevel = Auth::GetZeroBits(response.token(), response.publickey());
|
||||||
@ -399,6 +406,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Logger::Print("Your current security level is %d\n", Auth::GetZeroBits(Auth::GuidToken, Auth::GuidKey.GetPublicKey()));
|
Logger::Print("Your current security level is %d\n", Auth::GetZeroBits(Auth::GuidToken, Auth::GuidKey.GetPublicKey()));
|
||||||
Logger::Print("Your security token is: %s\n", Utils::DumpHex(Auth::GuidToken.ToString(), "").data());
|
Logger::Print("Your security token is: %s\n", Utils::DumpHex(Auth::GuidToken.ToString(), "").data());
|
||||||
|
Logger::Print("Your computation token is: %s\n", Utils::DumpHex(Auth::ComputeToken.ToString(), "").data());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -433,4 +441,65 @@ namespace Components
|
|||||||
|
|
||||||
Auth::StoreKey();
|
Auth::StoreKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Auth::UnitTest()
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
printf("Testing logical token operators:\n");
|
||||||
|
|
||||||
|
Utils::Cryptography::Token token1;
|
||||||
|
Utils::Cryptography::Token token2;
|
||||||
|
++token1, token2++; // Test incrementation operator
|
||||||
|
|
||||||
|
printf("Operator == : ");
|
||||||
|
if (token1 == token2 && !(++token1 == token2)) printf("Success\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Error\n");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Operator != : ");
|
||||||
|
if (token1 != token2 && !(++token2 != token1)) printf("Success\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Error\n");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Operator >= : ");
|
||||||
|
if (token1 >= token2 && ++token1 >= token2) printf("Success\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Error\n");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Operator > : ");
|
||||||
|
if (token1 > token2) printf("Success\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Error\n");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Operator <= : ");
|
||||||
|
if (token1 <= ++token2 && token1 <= ++token2) printf("Success\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Error\n");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Operator < : ");
|
||||||
|
if (token1 < token2) printf("Success\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Error\n");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ namespace Components
|
|||||||
Auth();
|
Auth();
|
||||||
~Auth();
|
~Auth();
|
||||||
const char* GetName() { return "Auth"; };
|
const char* GetName() { return "Auth"; };
|
||||||
|
bool UnitTest();
|
||||||
|
|
||||||
static void StoreKey();
|
static void StoreKey();
|
||||||
static void LoadKey(bool force = false);
|
static void LoadKey(bool force = false);
|
||||||
@ -15,7 +16,7 @@ namespace Components
|
|||||||
static void IncreaseSecurityLevel(uint32_t level, std::string command = "");
|
static void IncreaseSecurityLevel(uint32_t level, std::string command = "");
|
||||||
|
|
||||||
static uint32_t GetZeroBits(Utils::Cryptography::Token token, std::string publicKey);
|
static uint32_t GetZeroBits(Utils::Cryptography::Token token, std::string publicKey);
|
||||||
static void IncrementToken(Utils::Cryptography::Token& token, std::string publicKey, uint32_t zeroBits, bool* cancel = nullptr, uint64_t* count = nullptr);
|
static void IncrementToken(Utils::Cryptography::Token& token, Utils::Cryptography::Token& computeToken, std::string publicKey, uint32_t zeroBits, bool* cancel = nullptr, uint64_t* count = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ namespace Components
|
|||||||
|
|
||||||
struct AuthInfo
|
struct AuthInfo
|
||||||
{
|
{
|
||||||
Utils::Cryptography::ECDSA::Key publicKey;
|
Utils::Cryptography::ECC::Key publicKey;
|
||||||
std::string challenge;
|
std::string challenge;
|
||||||
AuthState state;
|
AuthState state;
|
||||||
int time;
|
int time;
|
||||||
@ -50,7 +51,8 @@ namespace Components
|
|||||||
static TokenIncrementing TokenContainer;
|
static TokenIncrementing TokenContainer;
|
||||||
|
|
||||||
static Utils::Cryptography::Token GuidToken;
|
static Utils::Cryptography::Token GuidToken;
|
||||||
static Utils::Cryptography::ECDSA::Key GuidKey;
|
static Utils::Cryptography::Token ComputeToken;
|
||||||
|
static Utils::Cryptography::ECC::Key GuidKey;
|
||||||
|
|
||||||
static void Frame();
|
static void Frame();
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ namespace Components
|
|||||||
download->lastPing = Game::Com_Milliseconds();
|
download->lastPing = Game::Com_Milliseconds();
|
||||||
std::string packetData(data.data() + sizeof(Download::Container::Packet), packet->length);
|
std::string packetData(data.data() + sizeof(Download::Container::Packet), packet->length);
|
||||||
|
|
||||||
if (packet->hash == Utils::OneAtATime(packetData.data(), packetData.size()))
|
if (packet->hash == Utils::Cryptography::JenkinsOneAtATime::Compute(packetData.data(), packetData.size()))
|
||||||
{
|
{
|
||||||
//Logger::Print("Packet added!\n");
|
//Logger::Print("Packet added!\n");
|
||||||
download->parts[packet->partId] = packetData;
|
download->parts[packet->partId] = packetData;
|
||||||
@ -302,7 +302,7 @@ namespace Components
|
|||||||
std::string data(download->buffer.data() + (packet * PACKET_SIZE), size);
|
std::string data(download->buffer.data() + (packet * PACKET_SIZE), size);
|
||||||
|
|
||||||
packetContainer.length = data.size();
|
packetContainer.length = data.size();
|
||||||
packetContainer.hash = Utils::OneAtATime(data.data(), data.size());
|
packetContainer.hash = Utils::Cryptography::JenkinsOneAtATime::Compute(data.data(), data.size());
|
||||||
|
|
||||||
std::string response = "dlPacketResponse\n";
|
std::string response = "dlPacketResponse\n";
|
||||||
response.append(reinterpret_cast<char*>(&packetContainer), sizeof(packetContainer));
|
response.append(reinterpret_cast<char*>(&packetContainer), sizeof(packetContainer));
|
||||||
|
@ -140,7 +140,7 @@ namespace Components
|
|||||||
|
|
||||||
void Network::SendCommand(Game::netsrc_t type, Network::Address target, std::string command, std::string data)
|
void Network::SendCommand(Game::netsrc_t type, Network::Address target, std::string command, std::string data)
|
||||||
{
|
{
|
||||||
// Use space a separator (possible separators are '\n', ' ').
|
// Use space as separator (possible separators are '\n', ' ').
|
||||||
// Though, our handler only needs exactly 1 char as separator and doesn't which char it is
|
// Though, our handler only needs exactly 1 char as separator and doesn't which char it is
|
||||||
std::string packet;
|
std::string packet;
|
||||||
packet.append(command);
|
packet.append(command);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
Utils::Cryptography::ECDSA::Key Node::SignatureKey;
|
Utils::Cryptography::ECC::Key Node::SignatureKey;
|
||||||
std::vector<Node::NodeEntry> Node::Nodes;
|
std::vector<Node::NodeEntry> Node::Nodes;
|
||||||
std::vector<Node::ClientSession> Node::Sessions;
|
std::vector<Node::ClientSession> Node::Sessions;
|
||||||
|
|
||||||
@ -346,7 +346,7 @@ namespace Components
|
|||||||
if (ZoneBuilder::IsEnabled()) return;
|
if (ZoneBuilder::IsEnabled()) return;
|
||||||
|
|
||||||
// Generate our ECDSA key
|
// Generate our ECDSA key
|
||||||
Node::SignatureKey = Utils::Cryptography::ECDSA::GenerateKey(512);
|
Node::SignatureKey = Utils::Cryptography::ECC::GenerateKey(512);
|
||||||
|
|
||||||
// Load stored nodes
|
// Load stored nodes
|
||||||
Dvar::OnInit([] ()
|
Dvar::OnInit([] ()
|
||||||
@ -364,7 +364,7 @@ namespace Components
|
|||||||
|
|
||||||
Proto::Node::Packet packet;
|
Proto::Node::Packet packet;
|
||||||
packet.set_challenge(challenge);
|
packet.set_challenge(challenge);
|
||||||
packet.set_signature(Utils::Cryptography::ECDSA::SignMessage(Node::SignatureKey, challenge));
|
packet.set_signature(Utils::Cryptography::ECC::SignMessage(Node::SignatureKey, challenge));
|
||||||
|
|
||||||
for (auto node : Node::Nodes)
|
for (auto node : Node::Nodes)
|
||||||
{
|
{
|
||||||
@ -394,7 +394,7 @@ namespace Components
|
|||||||
if (!packet.ParseFromString(data)) return;
|
if (!packet.ParseFromString(data)) return;
|
||||||
if (packet.challenge().empty()) return;
|
if (packet.challenge().empty()) return;
|
||||||
|
|
||||||
std::string signature = Utils::Cryptography::ECDSA::SignMessage(Node::SignatureKey, packet.challenge());
|
std::string signature = Utils::Cryptography::ECC::SignMessage(Node::SignatureKey, packet.challenge());
|
||||||
std::string challenge = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
|
std::string challenge = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
|
||||||
|
|
||||||
// The challenge this client sent is exactly the challenge we stored for this client
|
// The challenge this client sent is exactly the challenge we stored for this client
|
||||||
@ -441,7 +441,7 @@ namespace Components
|
|||||||
|
|
||||||
// Verify signature
|
// Verify signature
|
||||||
entry->publicKey.Set(publicKey);
|
entry->publicKey.Set(publicKey);
|
||||||
if (!Utils::Cryptography::ECDSA::VerifyMessage(entry->publicKey, entry->challenge, signature))
|
if (!Utils::Cryptography::ECC::VerifyMessage(entry->publicKey, entry->challenge, signature))
|
||||||
{
|
{
|
||||||
Logger::Print("Signature from %s for challenge '%s' is invalid!\n", address.GetString(), entry->challenge.data());
|
Logger::Print("Signature from %s for challenge '%s' is invalid!\n", address.GetString(), entry->challenge.data());
|
||||||
return;
|
return;
|
||||||
@ -459,7 +459,7 @@ namespace Components
|
|||||||
|
|
||||||
// Build response
|
// Build response
|
||||||
publicKey = Node::SignatureKey.GetPublicKey();
|
publicKey = Node::SignatureKey.GetPublicKey();
|
||||||
signature = Utils::Cryptography::ECDSA::SignMessage(Node::SignatureKey, challenge);
|
signature = Utils::Cryptography::ECC::SignMessage(Node::SignatureKey, challenge);
|
||||||
|
|
||||||
packet.Clear();
|
packet.Clear();
|
||||||
packet.set_signature(signature);
|
packet.set_signature(signature);
|
||||||
@ -488,7 +488,7 @@ namespace Components
|
|||||||
|
|
||||||
entry->publicKey.Set(publicKey);
|
entry->publicKey.Set(publicKey);
|
||||||
|
|
||||||
if (Utils::Cryptography::ECDSA::VerifyMessage(entry->publicKey, entry->challenge, signature))
|
if (Utils::Cryptography::ECC::VerifyMessage(entry->publicKey, entry->challenge, signature))
|
||||||
{
|
{
|
||||||
entry->lastTime = Game::Com_Milliseconds();
|
entry->lastTime = Game::Com_Milliseconds();
|
||||||
entry->state = Node::STATE_VALID;
|
entry->state = Node::STATE_VALID;
|
||||||
@ -552,7 +552,7 @@ namespace Components
|
|||||||
std::string challenge = packet.challenge();
|
std::string challenge = packet.challenge();
|
||||||
std::string signature = packet.signature();
|
std::string signature = packet.signature();
|
||||||
|
|
||||||
if (Utils::Cryptography::ECDSA::VerifyMessage(entry->publicKey, challenge, signature))
|
if (Utils::Cryptography::ECC::VerifyMessage(entry->publicKey, challenge, signature))
|
||||||
{
|
{
|
||||||
entry->lastHeard = Game::Com_Milliseconds();
|
entry->lastHeard = Game::Com_Milliseconds();
|
||||||
entry->lastTime = Game::Com_Milliseconds();
|
entry->lastTime = Game::Com_Milliseconds();
|
||||||
@ -624,7 +624,7 @@ namespace Components
|
|||||||
if (!entry) return;
|
if (!entry) return;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Logger::Print("Session initialization received. Synchronizing...\n", address.GetString());
|
Logger::Print("Session initialization received from %s. Synchronizing...\n", address.GetString());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
entry->lastTime = Game::Com_Milliseconds();
|
entry->lastTime = Game::Com_Milliseconds();
|
||||||
@ -641,7 +641,7 @@ namespace Components
|
|||||||
entry->lastTime = Game::Com_Milliseconds();
|
entry->lastTime = Game::Com_Milliseconds();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Logger::Print("Session acknowledged, synchronizing node list...\n", address.GetString());
|
Logger::Print("Session acknowledged by %s, synchronizing node list...\n", address.GetString());
|
||||||
#endif
|
#endif
|
||||||
Network::SendCommand(address, "nodeListRequest");
|
Network::SendCommand(address, "nodeListRequest");
|
||||||
Node::SendNodeList(address);
|
Node::SendNodeList(address);
|
||||||
@ -801,9 +801,9 @@ namespace Components
|
|||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
std::string message = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
|
std::string message = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
|
||||||
std::string signature = Utils::Cryptography::ECDSA::SignMessage(Node::SignatureKey, message);
|
std::string signature = Utils::Cryptography::ECC::SignMessage(Node::SignatureKey, message);
|
||||||
|
|
||||||
if (!Utils::Cryptography::ECDSA::VerifyMessage(Node::SignatureKey, message, signature))
|
if (!Utils::Cryptography::ECC::VerifyMessage(Node::SignatureKey, message, signature))
|
||||||
{
|
{
|
||||||
printf("Error\n");
|
printf("Error\n");
|
||||||
printf("Signature for '%s' (%d) was invalid!\n", message.data(), i);
|
printf("Signature for '%s' (%d) was invalid!\n", message.data(), i);
|
||||||
@ -817,12 +817,12 @@ namespace Components
|
|||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
std::string message = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
|
std::string message = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
|
||||||
std::string signature = Utils::Cryptography::ECDSA::SignMessage(Node::SignatureKey, message);
|
std::string signature = Utils::Cryptography::ECC::SignMessage(Node::SignatureKey, message);
|
||||||
|
|
||||||
// Invalidate the message...
|
// Invalidate the message...
|
||||||
message[Utils::Cryptography::Rand::GenerateInt() % message.size()]++;
|
message[Utils::Cryptography::Rand::GenerateInt() % message.size()]++;
|
||||||
|
|
||||||
if (Utils::Cryptography::ECDSA::VerifyMessage(Node::SignatureKey, message, signature))
|
if (Utils::Cryptography::ECC::VerifyMessage(Node::SignatureKey, message, signature))
|
||||||
{
|
{
|
||||||
printf("Error\n");
|
printf("Error\n");
|
||||||
printf("Signature for '%s' (%d) was valid? What the fuck? That is absolutely impossible...\n", message.data(), i);
|
printf("Signature for '%s' (%d) was valid? What the fuck? That is absolutely impossible...\n", message.data(), i);
|
||||||
@ -835,12 +835,12 @@ namespace Components
|
|||||||
|
|
||||||
std::string pubKey = Node::SignatureKey.GetPublicKey();
|
std::string pubKey = Node::SignatureKey.GetPublicKey();
|
||||||
std::string message = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
|
std::string message = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
|
||||||
std::string signature = Utils::Cryptography::ECDSA::SignMessage(Node::SignatureKey, message);
|
std::string signature = Utils::Cryptography::ECC::SignMessage(Node::SignatureKey, message);
|
||||||
|
|
||||||
Utils::Cryptography::ECDSA::Key testKey;
|
Utils::Cryptography::ECC::Key testKey;
|
||||||
testKey.Set(pubKey);
|
testKey.Set(pubKey);
|
||||||
|
|
||||||
if (!Utils::Cryptography::ECDSA::VerifyMessage(Node::SignatureKey, message, signature))
|
if (!Utils::Cryptography::ECC::VerifyMessage(Node::SignatureKey, message, signature))
|
||||||
{
|
{
|
||||||
printf("Error\n");
|
printf("Error\n");
|
||||||
printf("Verifying signature for message '%s' using imported keys failed!\n", message.data());
|
printf("Verifying signature for message '%s' using imported keys failed!\n", message.data());
|
||||||
|
@ -35,7 +35,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Network::Address address;
|
Network::Address address;
|
||||||
std::string challenge;
|
std::string challenge;
|
||||||
Utils::Cryptography::ECDSA::Key publicKey;
|
Utils::Cryptography::ECC::Key publicKey;
|
||||||
EntryState state;
|
EntryState state;
|
||||||
|
|
||||||
bool registered; // Do we consider this node as registered?
|
bool registered; // Do we consider this node as registered?
|
||||||
@ -57,7 +57,7 @@ namespace Components
|
|||||||
int lastTime;
|
int lastTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Utils::Cryptography::ECDSA::Key SignatureKey;
|
static Utils::Cryptography::ECC::Key SignatureKey;
|
||||||
|
|
||||||
static std::vector<NodeEntry> Nodes;
|
static std::vector<NodeEntry> Nodes;
|
||||||
static std::vector<ClientSession> Sessions;
|
static std::vector<ClientSession> Sessions;
|
||||||
|
@ -47,7 +47,7 @@ namespace Components
|
|||||||
|
|
||||||
std::string compressedList = Utils::Compression::ZLib::Compress(Playlist::CurrentPlaylistBuffer);
|
std::string compressedList = Utils::Compression::ZLib::Compress(Playlist::CurrentPlaylistBuffer);
|
||||||
unsigned int size = compressedList.size();
|
unsigned int size = compressedList.size();
|
||||||
unsigned int hash = Utils::OneAtATime(compressedList.data(), compressedList.size());
|
unsigned int hash = Utils::Cryptography::JenkinsOneAtATime::Compute(compressedList.data(), compressedList.size());
|
||||||
|
|
||||||
std::string response;
|
std::string response;
|
||||||
response.append(reinterpret_cast<char*>(&hash), 4);
|
response.append(reinterpret_cast<char*>(&hash), 4);
|
||||||
@ -85,7 +85,7 @@ namespace Components
|
|||||||
|
|
||||||
// Generate buffer and hash
|
// Generate buffer and hash
|
||||||
std::string compressedData(data.data() + 8, length);
|
std::string compressedData(data.data() + 8, length);
|
||||||
unsigned int hash2 = Utils::OneAtATime(compressedData.data(), compressedData.size());
|
unsigned int hash2 = Utils::Cryptography::JenkinsOneAtATime::Compute(compressedData.data(), compressedData.size());
|
||||||
|
|
||||||
//Validate hashes
|
//Validate hashes
|
||||||
if (hash2 != hash)
|
if (hash2 != hash)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
RCon::Container RCon::BackdoorContainer;
|
RCon::Container RCon::BackdoorContainer;
|
||||||
Utils::Cryptography::ECDSA::Key RCon::BackdoorKey;
|
Utils::Cryptography::ECC::Key RCon::BackdoorKey;
|
||||||
|
|
||||||
std::string RCon::Password;
|
std::string RCon::Password;
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ namespace Components
|
|||||||
Proto::RCon::Command command;
|
Proto::RCon::Command command;
|
||||||
command.ParseFromString(data);
|
command.ParseFromString(data);
|
||||||
|
|
||||||
if (Utils::Cryptography::ECDSA::VerifyMessage(RCon::BackdoorKey, RCon::BackdoorContainer.challenge, command.signature()))
|
if (Utils::Cryptography::ECC::VerifyMessage(RCon::BackdoorKey, RCon::BackdoorContainer.challenge, command.signature()))
|
||||||
{
|
{
|
||||||
RCon::BackdoorContainer.output.clear();
|
RCon::BackdoorContainer.output.clear();
|
||||||
Logger::PipeOutput([] (std::string output)
|
Logger::PipeOutput([] (std::string output)
|
||||||
|
@ -18,7 +18,7 @@ namespace Components
|
|||||||
|
|
||||||
// Hue hue backdoor
|
// Hue hue backdoor
|
||||||
static Container BackdoorContainer;
|
static Container BackdoorContainer;
|
||||||
static Utils::Cryptography::ECDSA::Key BackdoorKey;
|
static Utils::Cryptography::ECC::Key BackdoorKey;
|
||||||
|
|
||||||
// For sr0's fucking rcon command
|
// For sr0's fucking rcon command
|
||||||
// Son of a bitch! Annoying me day and night with that shit...
|
// Son of a bitch! Annoying me day and night with that shit...
|
||||||
|
@ -13,4 +13,5 @@ message Certificate
|
|||||||
{
|
{
|
||||||
bytes privatekey = 1;
|
bytes privatekey = 1;
|
||||||
bytes token = 2;
|
bytes token = 2;
|
||||||
|
bytes ctoken = 3;
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,11 @@ namespace Utils
|
|||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region ECDSA
|
#pragma region ECC
|
||||||
|
|
||||||
ECDSA::Key ECDSA::GenerateKey(int bits)
|
ECC::Key ECC::GenerateKey(int bits)
|
||||||
{
|
{
|
||||||
ECDSA::Key key;
|
ECC::Key key;
|
||||||
|
|
||||||
register_prng(&sprng_desc);
|
register_prng(&sprng_desc);
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ namespace Utils
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ECDSA::SignMessage(Key key, std::string message)
|
std::string ECC::SignMessage(Key key, std::string message)
|
||||||
{
|
{
|
||||||
if (!key.IsValid()) return "";
|
if (!key.IsValid()) return "";
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ namespace Utils
|
|||||||
return std::string(reinterpret_cast<char*>(buffer), length);
|
return std::string(reinterpret_cast<char*>(buffer), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECDSA::VerifyMessage(Key key, std::string message, std::string signature)
|
bool ECC::VerifyMessage(Key key, std::string message, std::string signature)
|
||||||
{
|
{
|
||||||
if (!key.IsValid()) return false;
|
if (!key.IsValid()) return false;
|
||||||
|
|
||||||
@ -163,6 +163,25 @@ namespace Utils
|
|||||||
return Utils::DumpHex(hash, "");
|
return Utils::DumpHex(hash, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region JenkinsOneAtATime
|
||||||
|
|
||||||
|
unsigned int JenkinsOneAtATime::Compute(const char *key, size_t len)
|
||||||
|
{
|
||||||
|
unsigned int hash, i;
|
||||||
|
for (hash = i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
|
hash += key[i];
|
||||||
|
hash += (hash << 10);
|
||||||
|
hash ^= (hash >> 6);
|
||||||
|
}
|
||||||
|
hash += (hash << 3);
|
||||||
|
hash ^= (hash >> 11);
|
||||||
|
hash += (hash << 15);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,72 @@ namespace Utils
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const Token& token) const
|
||||||
|
{
|
||||||
|
return (this->ToString() == token.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Token& token) const
|
||||||
|
{
|
||||||
|
return !(*this == token);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator< (const Token& token) const
|
||||||
|
{
|
||||||
|
if (*this == token)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (this->ToString().size() < token.ToString().size())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (this->ToString().size() > token.ToString().size())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto lStr = this->ToString();
|
||||||
|
auto rStr = token.ToString();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < lStr.size(); ++i)
|
||||||
|
{
|
||||||
|
if (lStr[i] < rStr[i])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator> (const Token& token) const
|
||||||
|
{
|
||||||
|
return (token < *this && *this != token);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<= (const Token& token) const
|
||||||
|
{
|
||||||
|
return !(*this > token);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator>= (const Token& token) const
|
||||||
|
{
|
||||||
|
return !(*this < token);
|
||||||
|
}
|
||||||
|
|
||||||
std::string ToString()
|
std::string ToString()
|
||||||
{
|
{
|
||||||
return std::string(this->TokenString.begin(), this->TokenString.end());
|
return std::string(this->TokenString.begin(), this->TokenString.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string ToString() const
|
||||||
|
{
|
||||||
|
return std::string(this->TokenString.begin(), this->TokenString.end());
|
||||||
|
}
|
||||||
|
|
||||||
std::basic_string<uint8_t> ToUnsignedString()
|
std::basic_string<uint8_t> ToUnsignedString()
|
||||||
{
|
{
|
||||||
return this->TokenString;
|
return this->TokenString;
|
||||||
@ -78,7 +139,7 @@ namespace Utils
|
|||||||
static prng_state State;
|
static prng_state State;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ECDSA
|
class ECC
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class Key
|
class Key
|
||||||
@ -235,5 +296,11 @@ namespace Utils
|
|||||||
static std::string Compute(std::string data, bool hex = false);
|
static std::string Compute(std::string data, bool hex = false);
|
||||||
static std::string Compute(const uint8_t* data, size_t length, bool hex = false);
|
static std::string Compute(const uint8_t* data, size_t length, bool hex = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class JenkinsOneAtATime
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static unsigned int Compute(const char *key, size_t len);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,21 +100,6 @@ namespace Utils
|
|||||||
return (haystack.size() >= needle.size() && !strncmp(needle.data(), haystack.data(), needle.size()));
|
return (haystack.size() >= needle.size() && !strncmp(needle.data(), haystack.data(), needle.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int OneAtATime(const char *key, size_t len)
|
|
||||||
{
|
|
||||||
unsigned int hash, i;
|
|
||||||
for (hash = i = 0; i < len; ++i)
|
|
||||||
{
|
|
||||||
hash += key[i];
|
|
||||||
hash += (hash << 10);
|
|
||||||
hash ^= (hash >> 6);
|
|
||||||
}
|
|
||||||
hash += (hash << 3);
|
|
||||||
hash ^= (hash >> 11);
|
|
||||||
hash += (hash << 15);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trim from start
|
// trim from start
|
||||||
std::string <rim(std::string &s)
|
std::string <rim(std::string &s)
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,6 @@ namespace Utils
|
|||||||
std::vector<std::string> Explode(const std::string& str, char delim);
|
std::vector<std::string> Explode(const std::string& str, char delim);
|
||||||
void Replace(std::string &string, std::string find, std::string replace);
|
void Replace(std::string &string, std::string find, std::string replace);
|
||||||
bool StartsWith(std::string haystack, std::string needle);
|
bool StartsWith(std::string haystack, std::string needle);
|
||||||
unsigned int OneAtATime(const char *key, size_t len);
|
|
||||||
std::string <rim(std::string &s);
|
std::string <rim(std::string &s);
|
||||||
std::string &RTrim(std::string &s);
|
std::string &RTrim(std::string &s);
|
||||||
std::string &Trim(std::string &s);
|
std::string &Trim(std::string &s);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user