367 lines
7.9 KiB
C++
367 lines
7.9 KiB
C++
#pragma once
|
|
|
|
namespace Utils
|
|
{
|
|
namespace Cryptography
|
|
{
|
|
void Initialize();
|
|
std::string GetEntropy();
|
|
|
|
class Token
|
|
{
|
|
public:
|
|
Token() { this->tokenString.clear(); }
|
|
Token(const Token& obj) : tokenString(obj.tokenString) { }
|
|
Token(const std::string& token) : tokenString(token.begin(), token.end()) { }
|
|
Token(const std::basic_string<std::uint8_t>& token) : tokenString(token.begin(), token.end()) { }
|
|
|
|
Token& operator++ ()
|
|
{
|
|
if (this->tokenString.empty())
|
|
{
|
|
this->tokenString.append(reinterpret_cast<std::uint8_t*>(const_cast<char *>("\0")), 1);
|
|
}
|
|
else
|
|
{
|
|
for (int i = static_cast<int>(this->tokenString.size() - 1); i >= 0; --i)
|
|
{
|
|
if (this->tokenString[i] == 0xFF)
|
|
{
|
|
this->tokenString[i] = 0;
|
|
|
|
if (!i)
|
|
{
|
|
this->tokenString = std::basic_string{ reinterpret_cast<std::uint8_t*>(const_cast<char*>("\0")), 1 } + this->tokenString;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
++this->tokenString[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
Token operator++ (int)
|
|
{
|
|
Token result = *this;
|
|
this->operator++();
|
|
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;
|
|
}
|
|
|
|
if (this->toString().size() < token.toString().size())
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (this->toString().size() > token.toString().size())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
auto lStr = this->toString();
|
|
auto rStr = token.toString();
|
|
|
|
for (std::size_t 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);
|
|
}
|
|
|
|
[[nodiscard]] std::string toString() const
|
|
{
|
|
return std::string{ this->tokenString.begin(), this->tokenString.end() };
|
|
}
|
|
|
|
[[nodiscard]] std::basic_string<std::uint8_t> toUnsignedString() const
|
|
{
|
|
return this->tokenString;
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
this->tokenString.clear();
|
|
}
|
|
|
|
private:
|
|
std::basic_string<uint8_t> tokenString;
|
|
};
|
|
|
|
class Rand
|
|
{
|
|
public:
|
|
static std::string GenerateChallenge();
|
|
static std::uint32_t GenerateInt();
|
|
static void Initialize();
|
|
|
|
private:
|
|
static prng_state State;
|
|
};
|
|
|
|
class ECC
|
|
{
|
|
public:
|
|
class Key
|
|
{
|
|
public:
|
|
Key() : keyStorage(new ecc_key)
|
|
{
|
|
ZeroMemory(this->getKeyPtr(), sizeof(*this->getKeyPtr()));
|
|
}
|
|
|
|
Key(ecc_key* key) : Key() { if (key) std::memmove(this->getKeyPtr(), key, sizeof(*key)); }
|
|
Key(ecc_key key) : Key(&key) {}
|
|
|
|
~Key()
|
|
{
|
|
if (this->keyStorage.use_count() <= 1)
|
|
{
|
|
this->free();
|
|
}
|
|
}
|
|
|
|
[[nodiscard]] bool isValid()
|
|
{
|
|
return (!Memory::IsSet(this->getKeyPtr(), 0, sizeof(*this->getKeyPtr())));
|
|
}
|
|
|
|
[[nodiscard]] ecc_key* getKeyPtr()
|
|
{
|
|
return this->keyStorage.get();
|
|
}
|
|
|
|
[[nodiscard]] std::string getPublicKey()
|
|
{
|
|
std::uint8_t buffer[512]{};
|
|
unsigned long length = sizeof(buffer);
|
|
|
|
if (ecc_ansi_x963_export(this->getKeyPtr(), buffer, &length) == CRYPT_OK)
|
|
{
|
|
return std::string{ reinterpret_cast<char*>(buffer), length };
|
|
}
|
|
|
|
return std::string{};
|
|
}
|
|
|
|
void set(const std::string& pubKeyBuffer)
|
|
{
|
|
this->free();
|
|
|
|
if (ecc_ansi_x963_import(reinterpret_cast<const std::uint8_t*>(pubKeyBuffer.data()), pubKeyBuffer.size(), this->getKeyPtr()) != CRYPT_OK)
|
|
{
|
|
ZeroMemory(this->getKeyPtr(), sizeof(*this->getKeyPtr()));
|
|
}
|
|
}
|
|
|
|
void deserialize(const std::string& key)
|
|
{
|
|
this->free();
|
|
|
|
if (ecc_import(reinterpret_cast<const std::uint8_t*>(key.data()), key.size(), this->getKeyPtr()) != CRYPT_OK)
|
|
{
|
|
ZeroMemory(this->getKeyPtr(), sizeof(*this->getKeyPtr()));
|
|
}
|
|
}
|
|
|
|
[[nodiscard]] std::string serialize(int type = PK_PRIVATE)
|
|
{
|
|
std::uint8_t buffer[4096]{};
|
|
unsigned long length = sizeof(buffer);
|
|
|
|
if (ecc_export(buffer, &length, type, this->getKeyPtr()) == CRYPT_OK)
|
|
{
|
|
return std::string{ reinterpret_cast<char*>(buffer), length };
|
|
}
|
|
|
|
return std::string{};
|
|
}
|
|
|
|
void free()
|
|
{
|
|
if (this->isValid())
|
|
{
|
|
ecc_free(this->getKeyPtr());
|
|
}
|
|
|
|
ZeroMemory(this->getKeyPtr(), sizeof(*this->getKeyPtr()));
|
|
}
|
|
|
|
bool operator==(Key& key)
|
|
{
|
|
return (this->isValid() && key.isValid() && this->serialize(PK_PUBLIC) == key.serialize(PK_PUBLIC));
|
|
}
|
|
|
|
private:
|
|
std::shared_ptr<ecc_key> keyStorage;
|
|
};
|
|
|
|
static Key GenerateKey(int bits);
|
|
static std::string SignMessage(Key key, const std::string& message);
|
|
static bool VerifyMessage(Key key, const std::string& message, const std::string& signature);
|
|
};
|
|
|
|
class RSA
|
|
{
|
|
public:
|
|
class Key
|
|
{
|
|
public:
|
|
Key() : keyStorage(new rsa_key)
|
|
{
|
|
ZeroMemory(this->getKeyPtr(), sizeof(*this->getKeyPtr()));
|
|
}
|
|
|
|
Key(rsa_key* key) : Key() { if (key) std::memmove(this->getKeyPtr(), key, sizeof(*key)); }
|
|
Key(rsa_key key) : Key(&key) {}
|
|
|
|
~Key()
|
|
{
|
|
if (this->keyStorage.use_count() <= 1)
|
|
{
|
|
this->free();
|
|
}
|
|
}
|
|
|
|
[[nodiscard]] bool isValid()
|
|
{
|
|
return (!Memory::IsSet(this->getKeyPtr(), 0, sizeof(*this->getKeyPtr())));
|
|
}
|
|
|
|
[[nodiscard]] rsa_key* getKeyPtr()
|
|
{
|
|
return this->keyStorage.get();
|
|
}
|
|
|
|
[[nodiscard]] std::string getPublicKey()
|
|
{
|
|
std::uint8_t buffer[4096]{};
|
|
unsigned long length = sizeof(buffer);
|
|
|
|
if (rsa_export(buffer, &length, PK_PUBLIC, this->getKeyPtr()) == CRYPT_OK)
|
|
{
|
|
return std::string{ reinterpret_cast<char*>(buffer), length };
|
|
}
|
|
|
|
return std::string{};
|
|
}
|
|
|
|
void set(const std::string& keyBuffer)
|
|
{
|
|
this->free();
|
|
|
|
if (rsa_import(reinterpret_cast<const std::uint8_t*>(keyBuffer.data()), keyBuffer.size(), this->getKeyPtr()) != CRYPT_OK)
|
|
{
|
|
ZeroMemory(this->getKeyPtr(), sizeof(*this->getKeyPtr()));
|
|
}
|
|
}
|
|
|
|
[[nodiscard]] std::string serialize(int type = PK_PRIVATE)
|
|
{
|
|
std::uint8_t buffer[4096]{};
|
|
unsigned long length = sizeof(buffer);
|
|
|
|
if (rsa_export(buffer, &length, type, this->getKeyPtr()) == CRYPT_OK)
|
|
{
|
|
return std::string{ reinterpret_cast<char*>(buffer), length };
|
|
}
|
|
|
|
return std::string{};
|
|
}
|
|
|
|
void free()
|
|
{
|
|
if (this->isValid())
|
|
{
|
|
rsa_free(this->getKeyPtr());
|
|
}
|
|
|
|
ZeroMemory(this->getKeyPtr(), sizeof(*this->getKeyPtr()));
|
|
}
|
|
|
|
private:
|
|
std::shared_ptr<rsa_key> keyStorage;
|
|
};
|
|
|
|
static Key GenerateKey(int bits);
|
|
static std::string SignMessage(Key key, const std::string& message);
|
|
static bool VerifyMessage(Key key, const std::string& message, const std::string& signature);
|
|
};
|
|
|
|
class Tiger
|
|
{
|
|
public:
|
|
static std::string Compute(const std::string& data, bool hex = false);
|
|
static std::string Compute(const std::uint8_t* data, std::size_t length, bool hex = false);
|
|
};
|
|
|
|
class SHA1
|
|
{
|
|
public:
|
|
static std::string Compute(const std::string& data, bool hex = false);
|
|
static std::string Compute(const std::uint8_t* data, std::size_t length, bool hex = false);
|
|
};
|
|
|
|
class SHA256
|
|
{
|
|
public:
|
|
static std::string Compute(const std::string& data, bool hex = false);
|
|
static std::string Compute(const std::uint8_t* data, std::size_t length, bool hex = false);
|
|
};
|
|
|
|
class SHA512
|
|
{
|
|
public:
|
|
static std::string Compute(const std::string& data, bool hex = false);
|
|
static std::string Compute(const std::uint8_t* data, std::size_t length, bool hex = false);
|
|
};
|
|
|
|
class JenkinsOneAtATime
|
|
{
|
|
public:
|
|
static std::size_t Compute(const std::string& data);
|
|
static std::size_t Compute(const char* key, std::size_t len);
|
|
};
|
|
}
|
|
}
|