410 lines
9.7 KiB
C++
410 lines
9.7 KiB
C++
|
|
#include <openssl/conf.h>
|
|
#include <openssl/ssl.h> /* core library */
|
|
#include "utils.h"
|
|
|
|
|
|
using namespace std;
|
|
|
|
const std::string base64_chars =
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
|
|
const char base64_url_alphabet[] = {
|
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
|
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'};
|
|
|
|
void getCharsFromString(string &source, char *charArray, size_t length)
|
|
{
|
|
for (size_t i = 0; i < length; i++)
|
|
{
|
|
charArray[i] = source[i];
|
|
}
|
|
}
|
|
|
|
void getCharsFromString(string source, char *charArray)
|
|
{
|
|
size_t length = source.length();
|
|
for (size_t i = 0; i < length; i++)
|
|
{
|
|
charArray[i] = source[i];
|
|
}
|
|
}
|
|
|
|
std::string right(const std::string &sourceString, size_t numChars)
|
|
{
|
|
if (numChars >= sourceString.size())
|
|
{
|
|
return sourceString; // If numChars is greater or equal to the string size, return the whole string.
|
|
}
|
|
return sourceString.substr(sourceString.size() - numChars);
|
|
}
|
|
|
|
uint16_t calculateCRC16(const uint8_t *data, size_t length)
|
|
{
|
|
const uint16_t polynomial = 0xA001; // CRC16-CCITT polynomial
|
|
uint16_t crc = 0xFFFF; // Initial value
|
|
|
|
for (size_t i = 0; i < length; i++)
|
|
{
|
|
crc ^= data[i]; // XOR with the current data byte
|
|
|
|
for (int j = 0; j < 8; j++)
|
|
{
|
|
if (crc & 0x0001)
|
|
{
|
|
crc = (crc >> 1) ^ polynomial;
|
|
}
|
|
else
|
|
{
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return crc;
|
|
}
|
|
|
|
uint16_t crc16(const unsigned char *data_p, unsigned char length)
|
|
{
|
|
uint16_t x;
|
|
uint16_t crc = 0xFFFF;
|
|
|
|
while (length--)
|
|
{
|
|
x = crc >> 8 ^ *data_p++;
|
|
x ^= x >> 4;
|
|
crc = (crc << 8) ^ ((unsigned short)(x << 12)) ^ ((unsigned short)(x << 5)) ^ ((unsigned short)x);
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
DATE getLicDate()
|
|
{
|
|
time_t ttime = time(0);
|
|
tm *local_time = localtime(&ttime);
|
|
int hoursSeconds = 3600 * local_time->tm_hour;
|
|
int minutesSeconds = 60 * local_time->tm_min;
|
|
int seconds = 1 * local_time->tm_sec;
|
|
int totalSeconds = hoursSeconds + minutesSeconds + seconds;
|
|
|
|
#ifdef WINDOWS
|
|
DATE dateOnly = ttime - totalSeconds + 7200; // (pro windows); // 7200 + vteřina za dvě hodiny pro srování
|
|
#else
|
|
DATE dateOnly = ttime - totalSeconds;
|
|
#endif
|
|
|
|
return dateOnly;
|
|
}
|
|
|
|
string getDate()
|
|
{
|
|
auto r = std::chrono::system_clock::now();
|
|
auto rp = std::chrono::system_clock::to_time_t(r);
|
|
std::string h(ctime(&rp)); // converting to c++ string
|
|
return h;
|
|
}
|
|
|
|
int encrypt(const unsigned char *plaintext, int plaintext_len, unsigned char *key,
|
|
unsigned char *iv, unsigned char *ciphertext)
|
|
{
|
|
EVP_CIPHER_CTX *ctx;
|
|
|
|
int len;
|
|
|
|
int ciphertext_len;
|
|
|
|
/* Create and initialise the context */
|
|
if (!(ctx = EVP_CIPHER_CTX_new())) return -1;
|
|
|
|
|
|
/*
|
|
* Initialise the encryption operation. IMPORTANT - ensure you use a key
|
|
* and IV size appropriate for your cipher
|
|
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
|
|
* IV size for *most* modes is the same as the block size. For AES this
|
|
* is 128 bits
|
|
*/
|
|
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
|
|
return -1;
|
|
|
|
/*
|
|
* Provide the message to be encrypted, and obtain the encrypted output.
|
|
* EVP_EncryptUpdate can be called multiple times if necessary
|
|
*/
|
|
if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
|
|
return -1;
|
|
ciphertext_len = len;
|
|
|
|
/*
|
|
* Finalise the encryption. Further ciphertext bytes may be written at
|
|
* this stage.
|
|
*/
|
|
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
|
|
return -1;
|
|
ciphertext_len += len;
|
|
|
|
/* Clean up */
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
|
|
return ciphertext_len;
|
|
}
|
|
|
|
int decrypt(const unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
|
|
unsigned char *iv, unsigned char *plaintext)
|
|
{
|
|
EVP_CIPHER_CTX *ctx;
|
|
|
|
int len;
|
|
|
|
int plaintext_len;
|
|
|
|
/* Create and initialise the context */
|
|
if (!(ctx = EVP_CIPHER_CTX_new()))
|
|
return -1;
|
|
|
|
/*
|
|
* Initialise the decryption operation. IMPORTANT - ensure you use a key
|
|
* and IV size appropriate for your cipher
|
|
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
|
|
* IV size for *most* modes is the same as the block size. For AES this
|
|
* is 128 bits
|
|
*/
|
|
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
|
|
return -1;
|
|
|
|
/*
|
|
* Provide the message to be decrypted, and obtain the plaintext output.
|
|
* EVP_DecryptUpdate can be called multiple times if necessary.
|
|
*/
|
|
if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
|
|
return -1;
|
|
plaintext_len = len;
|
|
|
|
/*
|
|
* Finalise the decryption. Further plaintext bytes may be written at
|
|
* this stage.
|
|
*/
|
|
if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len))
|
|
return -1;
|
|
|
|
plaintext_len += len;
|
|
|
|
/* Clean up */
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
|
|
return plaintext_len;
|
|
}
|
|
|
|
// converts character array
|
|
// to string and returns it
|
|
string convertToString(char *a, int size)
|
|
{
|
|
int i;
|
|
string s = "";
|
|
for (i = 0; i < size; i++)
|
|
{
|
|
s = s + a[i];
|
|
}
|
|
return s;
|
|
}
|
|
|
|
std::string base64_decode(const std::string &in)
|
|
{
|
|
std::string out;
|
|
std::vector<int> T(256, -1);
|
|
unsigned int i;
|
|
for (i = 0; i < 64; i++)
|
|
T[base64_url_alphabet[i]] = i;
|
|
|
|
int val = 0, valb = -8;
|
|
for (i = 0; i < in.length(); i++)
|
|
{
|
|
unsigned char c = in[i];
|
|
if (T[c] == -1)
|
|
break;
|
|
val = (val << 6) + T[c];
|
|
valb += 6;
|
|
if (valb >= 0)
|
|
{
|
|
out.push_back(char((val >> valb) & 0xFF));
|
|
valb -= 8;
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
std::string base64_encode_ai(const std::string &input)
|
|
{
|
|
std::string encoded;
|
|
|
|
size_t input_length = input.length();
|
|
size_t i = 0;
|
|
|
|
while (i < input_length)
|
|
{
|
|
unsigned char input_chunk[3] = {0};
|
|
size_t chunk_size = 0;
|
|
|
|
// Fill the input chunk with up to 3 bytes from the input string
|
|
for (size_t j = 0; j < 3; ++j)
|
|
{
|
|
if (i < input_length)
|
|
{
|
|
input_chunk[j] = input[i++];
|
|
++chunk_size;
|
|
}
|
|
}
|
|
|
|
// Encode the input chunk into 4 Base64 characters
|
|
encoded += base64_chars[(input_chunk[0] & 0xFC) >> 2];
|
|
encoded += base64_chars[((input_chunk[0] & 0x03) << 4) |
|
|
((input_chunk[1] & 0xF0) >> 4)];
|
|
encoded += (chunk_size > 1)
|
|
? base64_chars[((input_chunk[1] & 0x0F) << 2) |
|
|
((input_chunk[2] & 0xC0) >> 6)]
|
|
: '=';
|
|
encoded += (chunk_size > 2)
|
|
? base64_chars[input_chunk[2] & 0x3F]
|
|
: '=';
|
|
}
|
|
|
|
return encoded;
|
|
}
|
|
|
|
unordered_map<string, string> getArguments(int argc, char *argv[])
|
|
{
|
|
const char splitChar = '=';
|
|
unordered_map<string, string> result;
|
|
if (argc <= 1)
|
|
return result;
|
|
|
|
for (int i = 1; i < argc; ++i)
|
|
{
|
|
bool isArgName = true;
|
|
int argLength = strlen(argv[i]);
|
|
string argName;
|
|
string argValue;
|
|
|
|
for (int j = 0; j < argLength; j++)
|
|
{
|
|
if (argv[i][j] == splitChar)
|
|
{
|
|
isArgName = false;
|
|
continue;
|
|
}
|
|
|
|
if (isArgName)
|
|
{
|
|
argName += argv[i][j];
|
|
}
|
|
else
|
|
{
|
|
argValue += argv[i][j];
|
|
}
|
|
}
|
|
|
|
result.insert(make_pair(argName, argValue));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
string getCompletePath(string fileName)
|
|
{
|
|
#ifdef WINDOWS
|
|
return fileName;
|
|
#else
|
|
//warning TODO filesystem
|
|
char path[PATH_MAX+1] = {};
|
|
ssize_t length = readlink("/proc/self/exe", path, PATH_MAX);
|
|
path[length] = '\0';
|
|
string result = string(dirname(path)) + "/" + fileName;
|
|
return result;
|
|
//return std::string( result, (count > 0) ? count : 0 );
|
|
// std::filesystem::path exePath = std::filesystem::canonical("/proc/self/exe"); // / std::filesystem::path(argv[0]));
|
|
// std::filesystem::path fullPathOther = exePath.parent_path() / fileName;
|
|
// std::string fullPathStrOther = fullPathOther.string();
|
|
// return fullPathStrOther;
|
|
#endif
|
|
}
|
|
|
|
void appendStringToVector(const std::string &str, std::vector<unsigned char> &charVector)
|
|
{
|
|
size_t strLength = str.length();
|
|
for (size_t i = 0; i < strLength; ++i)
|
|
{
|
|
charVector.push_back(static_cast<unsigned char>(str[i]));
|
|
}
|
|
}
|
|
|
|
uint16_t calculateCRC16(std::vector<unsigned char> &charVector)
|
|
{
|
|
const uint16_t polynomial = 0xA001; // CRC16-CCITT polynomial
|
|
uint16_t crc = 0xFFFF; // Initial value
|
|
|
|
size_t length = charVector.size();
|
|
|
|
for (size_t i = 0; i < length; i++)
|
|
{
|
|
crc ^= charVector[i]; // XOR with the current data byte
|
|
|
|
for (int j = 0; j < 8; j++)
|
|
{
|
|
if (crc & 0x0001)
|
|
{
|
|
crc = (crc >> 1) ^ polynomial;
|
|
}
|
|
else
|
|
{
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return crc;
|
|
}
|
|
|
|
uint32_t bytesToDword(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4)
|
|
{
|
|
return static_cast<uint32_t>(byte1) |
|
|
(static_cast<uint32_t>(byte2) << 8) |
|
|
(static_cast<uint32_t>(byte3) << 16) |
|
|
(static_cast<uint32_t>(byte4) << 24);
|
|
}
|
|
|
|
uint32_t bytesToWord(uint8_t byte1, uint8_t byte2)
|
|
{
|
|
return static_cast<uint32_t>(byte1) | (static_cast<uint32_t>(byte2) << 8);
|
|
}
|
|
|
|
std::vector<unsigned char> joinVectors(const std::vector<unsigned char> &vector1, const std::vector<unsigned char> &vector2)
|
|
{
|
|
std::vector<unsigned char> result;
|
|
result.insert(result.end(), vector1.begin(), vector1.end());
|
|
result.insert(result.end(), vector2.begin(), vector2.end());
|
|
return result;
|
|
}
|
|
|
|
bool readFile(string fileName, vector<char> &output)
|
|
{
|
|
std::ifstream file(fileName, std::ios::in | std::ios::binary);
|
|
|
|
if (file.is_open() != 1)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
char byte;
|
|
while (file.get(byte))
|
|
{
|
|
// Convert the char to unsigned char and push it into the vector
|
|
output.push_back(byte);
|
|
}
|
|
|
|
file.close();
|
|
|
|
return true;
|
|
}
|