Move base/decode64 to crypto class

This commit is contained in:
Benau 2018-08-31 19:30:25 +08:00
parent 7fe6023e4f
commit 8873013911
5 changed files with 76 additions and 73 deletions

View File

@ -21,6 +21,53 @@
#include "network/network_string.hpp"
#include <openssl/aes.h>
#include <openssl/buffer.h>
#include <openssl/hmac.h>
// ============================================================================
std::string Crypto::base64(const std::vector<uint8_t>& input)
{
BIO *bmem, *b64;
BUF_MEM* bptr;
std::string result;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_set_flags(bmem, BIO_FLAGS_BASE64_NO_NL);
BIO_write(b64, input.data(), input.size());
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
result.resize(bptr->length - 1);
memcpy(&result[0], bptr->data, bptr->length - 1);
BIO_free_all(b64);
return result;
} // base64
// ============================================================================
std::vector<uint8_t> Crypto::decode64(std::string input)
{
BIO *b64, *bmem;
size_t decode_len = calcDecodeLength(input);
std::vector<uint8_t> result(decode_len, 0);
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new_mem_buf(&input[0], input.size());
bmem = BIO_push(b64, bmem);
BIO_set_flags(bmem, BIO_FLAGS_BASE64_NO_NL);
#ifdef DEBUG
size_t read_l = BIO_read(bmem, result.data(), input.size());
assert(read_l == decode_len);
#else
BIO_read(bmem, result.data(), input.size());
#endif
BIO_free_all(bmem);
return result;
} // decode64
// ============================================================================
std::string Crypto::m_client_key;

View File

@ -19,7 +19,7 @@
#ifndef HEADER_CRYPTO_HPP
#define HEADER_CRYPTO_HPP
#include "utils/string_utils.hpp"
#include "utils/log.hpp"
#include <enet/enet.h>
@ -55,14 +55,36 @@ private:
std::mutex m_crypto_mutex;
// ------------------------------------------------------------------------
static size_t calcDecodeLength(const std::string& input)
{
// Calculates the length of a decoded string
size_t padding = 0;
const size_t len = input.size();
if (input[len - 1] == '=' && input[len - 2] == '=')
{
// last two chars are =
padding = 2;
}
else if (input[len - 1] == '=')
{
// last char is =
padding = 1;
}
return (len * 3) / 4 - padding;
} // calcDecodeLength
public:
// ------------------------------------------------------------------------
static std::string base64(const std::vector<uint8_t>& input);
// ------------------------------------------------------------------------
static std::vector<uint8_t> decode64(std::string input);
// ------------------------------------------------------------------------
static std::unique_ptr<Crypto> getClientCrypto()
{
assert(!m_client_key.empty());
assert(!m_client_iv.empty());
auto c = std::unique_ptr<Crypto>(new Crypto(
StringUtils::decode64(m_client_key),
StringUtils::decode64(m_client_iv)));
auto c = std::unique_ptr<Crypto>(new Crypto(decode64(m_client_key),
decode64(m_client_iv)));
c->m_packet_counter = 1;
return c;
}
@ -84,8 +106,8 @@ public:
Log::warn("Crypto",
"Failed to generate cryptographically strong key");
}
m_client_key = StringUtils::base64(key);
m_client_iv = StringUtils::base64(iv);
m_client_key = base64(key);
m_client_iv = base64(iv);
}
// ------------------------------------------------------------------------
static void resetClientAES()

View File

@ -2015,7 +2015,7 @@ bool ServerLobby::decryptConnectionRequest(std::shared_ptr<STKPeer> peer,
uint32_t online_id, const core::stringw& online_name)
{
auto crypto = std::unique_ptr<Crypto>(new Crypto(
StringUtils::decode64(key), StringUtils::decode64(iv)));
Crypto::decode64(key), Crypto::decode64(iv)));
if (crypto->decryptConnectionRequest(data))
{
peer->setCrypto(std::move(crypto));

View File

@ -35,9 +35,6 @@
#include <cwchar>
#include <exception>
#include <openssl/hmac.h>
#include <openssl/buffer.h>
namespace StringUtils
{
bool hasSuffix(const std::string& lhs, const std::string &rhs)
@ -901,67 +898,6 @@ namespace StringUtils
return destination;
} //findAndReplace
// ------------------------------------------------------------------------
std::string base64(const std::vector<uint8_t>& input)
{
BIO *bmem, *b64;
BUF_MEM* bptr;
std::string result;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_set_flags(bmem, BIO_FLAGS_BASE64_NO_NL);
BIO_write(b64, input.data(), input.size());
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
result.resize(bptr->length - 1);
memcpy(&result[0], bptr->data, bptr->length - 1);
BIO_free_all(b64);
return result;
} //base64
// ------------------------------------------------------------------------
inline size_t calcDecodeLength(const std::string& input)
{
// Calculates the length of a decoded string
size_t padding = 0;
const size_t len = input.size();
if (input[len - 1] == '=' && input[len - 2] == '=')
{
// last two chars are =
padding = 2;
}
else if (input[len - 1] == '=')
{
// last char is =
padding = 1;
}
return (len * 3) / 4 - padding;
}
// ------------------------------------------------------------------------
std::vector<uint8_t> decode64(std::string input)
{
BIO *b64, *bmem;
size_t decode_len = calcDecodeLength(input);
std::vector<uint8_t> result(decode_len, 0);
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new_mem_buf(&input[0], input.size());
bmem = BIO_push(b64, bmem);
BIO_set_flags(bmem, BIO_FLAGS_BASE64_NO_NL);
#ifdef DEBUG
size_t read_l = BIO_read(bmem, result.data(), input.size());
assert(read_l == decode_len);
#else
BIO_read(bmem, result.data(), input.size());
#endif
BIO_free_all(bmem);
return result;
} //decode64
// ------------------------------------------------------------------------
std::string removeWhitespaces(const std::string& input)
{

View File

@ -244,8 +244,6 @@ namespace StringUtils
std::string wideToUtf8(const wchar_t* input);
std::string wideToUtf8(const irr::core::stringw& input);
std::string findAndReplace(const std::string& source, const std::string& find, const std::string& replace);
std::string base64(const std::vector<uint8_t>& input);
std::vector<uint8_t> decode64(std::string input);
std::string removeWhitespaces(const std::string& input);
} // namespace StringUtils