sd generator

This commit is contained in:
2023-08-17 09:04:39 +02:00
parent 4dc964360e
commit d531f56828
166 changed files with 44705 additions and 1 deletions

124
src/CreateLicence.cpp Normal file
View File

@@ -0,0 +1,124 @@
#include <stdio.h>
#include <map>
#include <cstring>
#include "plcLicence.h"
#include "utils.h"
#include <csignal>
#define FILEBUFFER 300
#define TWO_HOURSE_SECONDS 7200
void signalHandler(int signum) {
if (signum == SIGSEGV) {
std::cerr << "Caught segmentation fault (SIGSEGV)" << std::endl;
// You can perform some recovery actions here if needed
}
}
/// @brief hlavní funkce
/// @param argc
/// @param argv parametry pro generování licence
/// 1-cid, 2-csd, 3-stanice 4-rozvadec 5-typ licence
/// @return
int main(int argc, char *argv[])
{
std::signal(SIGSEGV, signalHandler);
// a segmentation fault
//int* ptr = nullptr;
//*ptr = 42; // This will trigger a segmentation fault
//map<string, const char *> arguments = mapArguments(argc, argv);
map<string, string> argumentsString = getArguments(argc, argv);
// std::cout << "Number of arguments: " << argc << std::endl;
// if (argc > 1)
// {
// for (int i = 1; i < argc; ++i)
// {
// arguments.insert(make_pair(to_string(i), argv[i]));
// }
// }
// else
// cerr << "Invalid arguments count";
// for (auto it = argumentsString.begin(); it != argumentsString.end(); ++it)
// {
// std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;
// }
// generatePause();
// return 1;
// for (int i = 0; i < argc; ++i)
// {
// std::cout << "Argument " << i << ": " << argv[i] << std::endl;
// cout << "size: " << strlen(argv[i]);
// }
// generatePause();
// return 1;
// if (argc >= 5)
// {
// cid = argv[1];
// csd = argv[2];
// stationName = argv[3];
// switchName = argv[4];
// licenceType = argv[5];
// }
// else
// {
// cout << "Par count error" << endl;
// }
// if (argc <= 1)
// {
// cid = "9f544930303030300000000b47015423";
// csd = "400e00325b5900003a0d7f800a40008d";
// stationName = "ceskatrebova";
// switchName = "RO1";
// licenceType = "2";
// binaryType = "2";
// }
// else
// {
// cid = argv[1];
// csd = argv[2];
// }
// cid = "9f544930303030300000000b47015423";
// csd = "400e00325b5900003a0d7f800a40008d";
// stationName = "ceskatrebova";
// switchName = "RO1";
// licenceType = "2";
// binaryType = "2";
// cout << "binaryType: " << binaryType;
// cout << "CID:" << argumentsString["-cid"];
const int cidLength = argumentsString["-cid"].length();
char cidArg[cidLength] = {};
getCharsFromString(argumentsString["-cid"], cidArg);
const int csdLength = argumentsString["-csd"].length();
char csdArg[csdLength] = {};
getCharsFromString(argumentsString["-csd"], csdArg);
//char cidTest = getCharArray(argumentsString["-cid"]);
//PlcLicence plcWriteLicence = PlcLicence(argumentsString);
//PlcLicence plcWriteLicence = PlcLicence(cidArg, csdArg, stationName, switchName, licenceType, binaryType, nullptr);
PlcLicence plcWriteLicence = PlcLicence(cidArg, csdArg, argumentsString["-outputType"], argumentsString["-configFileName"]);
// PlcLicence plcWriteLicence = PlcLicence(arguments["-cid"], arguments["-csd"], stationName, switchName, licenceType, binaryType, nullptr);
if (plcWriteLicence.CreateLicence() == false)
{
cerr << "Licence creation failed";
}
return EXIT_SUCCESS;
}

2
src/CreateLicence.d Normal file
View File

@@ -0,0 +1,2 @@
src/CreateLicence.o: src/CreateLicence.cpp include/plcLicence.h \
include/utils.h

BIN
src/CreateLicence.o Normal file

Binary file not shown.

943
src/PlcLicence.cpp Normal file
View File

@@ -0,0 +1,943 @@
#include <cstring>
#include <fstream>
#include "plcLicence.h"
#include "utils.h"
const std::string cEzLic_p78ou3_sdinfofilepath = "/sys/block/mmcblk0/device/";
const std::string cEzLic_p78ou3_licencfilepath_f21 = "/mnt/mmc/ez_sys/licence/";
const std::string cEzLic_p78ou3_licencfilepath_f17 = "/home/admin/ez/licence/";
const string cEzLic_p78ou3_licencfilepath_f10 = "/root/ez_sys/licence/";
const WORD cEzLic_p78ou3_maxDataToFile = 10000; // velikost datoveho bufferu pro ulozeni dat licence
const BYTE cEzLic_p78ou3_licMaxCount = 100;
const DWORD cEzLic_p78ou3_CheckLicNumber_ERR = 0xFFFFFFFF; // 16#FFFFFFFF; // chybna identifikace licence
const DWORD cEzLic_p78ou3_CheckLicNumber_EOV1 = 3781234965; // cislo pro overeni licence EOV, OSV verze 1
const BYTE cEzLic_p78ou3_CheckLicNumberId_ERR = 0; // id licence pro neidentifikovanou licenci
const BYTE cEzLic_p78ou3_CheckLicNumberId_EOV1 = 1; // id licence pro EOV, OSV verze 1
const BYTE cEzLic_p78ou3_MaxCheckLicNumberId = cEzLic_p78ou3_CheckLicNumberId_EOV1; // pocet identifikatoru licenci
const DWORD cEzLic_p78ou3_CheckLicNumber[] = {cEzLic_p78ou3_CheckLicNumber_ERR, cEzLic_p78ou3_CheckLicNumber_EOV1};
const WORD cEzLic_p78ou3_LicPrefixType_ELC1 = 1; // prefix typ1 = pouze zasifrovani dat
const WORD cEzLic_p78ou3_HeaderType_10 = 10; // hlavicka kriptovane casti verze 1.0
const WORD cEzLic_p78ou3_DataType_10 = 10; // data licence verze 1.0
const WORD cEzLic_p78ou3_SubType_10_10 = 0x0A0A; // subtype - verze hlavicky + verze data -> cEzLic_p78ou3_HeaderType_XX * 256 + cEzLic_p78ou3_DataType_XX
// ID aplikace
const WORD cEzLic_p78ou3_IDType_DDTS = 1; // aplikace DDTS
const WORD cEzLic_p78ou3_IDType_EOVOSV = 2; // aplikace EOV-OSV
const WORD cEzLic_p78ou3_IDType_DRT = 3; // aplikace DRT
std::string cEzLic_p78ou3_IDTypeStrData[] = {"neznamo", "DDTS", "EOV-OSV", "DRT"};
const BYTE cnibblescount = 32;
std::string cSDMonthStr[] = {"-", "I.", "II.", "III.", "IV.", "V.", "VI.", "VII.", "VIII.", "IX.", "X.", "XI.", "XII.", "-", "-", "-"};
BYTE cHexNibble_to_No[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 0, 0, 0, 0, 0, 0,
10, 11, 12, 13, 14, 15,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
10, 11, 12, 13, 14, 15,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
std::string cEzLic_p78ou3_CipherAES = "aes-256-cbc"; // konfigurace kriptovaciho algoritmu
PlcLicence::PlcLicence()
{
}
/// @brief process config file
/// @param dataFileName
void PlcLicence::processConfigFile(string &dataFileName)
{
std::string content;
std::ifstream inputFile(dataFileName);
if (inputFile.is_open())
{
content.assign((std::istreambuf_iterator<char>(inputFile)), (std::istreambuf_iterator<char>()));
inputFile.close();
//std::cout << "File content:\n" << content << std::endl;
}
else
{
std::cerr << "Unable to open the file." << std::endl;
}
string station = getXmlContentFromString(content, "station");
string distributor = getXmlContentFromString(content, "distributor");
// cout << station;
// cout << distributor;
this->stationName = station;
this->distributor = distributor;
// char stationCh[station.length()] = {};
// getCharsFromString(station, stationCh);
// char distributorCh[distributor.length()] = {};
// getCharsFromString(distributor, distributorCh);
// this->stationName = stationCh;
// this->distributor = distributorCh;
// cout << this->stationName << "\n";
// cout << this->distributor << "\n";
// this->stationName = "ceskatrebova";
// this->distributor = "RO1";
// cout << this->stationName << "\n";
// cout << this->distributor << "\n";
}
PlcLicence::PlcLicence(map<string, string> &arguments)
{
if (arguments.count("-cid") > 0)
{
const int cidLength = arguments["-cid"].length();
cout << "\n";
cout << "argument: " << arguments["-cid"] << endl;
cout << "argument delka: " << arguments["-cid"].length() << endl;
char cidArg[cidLength] = {};
getCharsFromString1(arguments["-cid"], cidArg);
this->cid = cidArg;
cout << "\n"
<< "CID 1:" << cid << " delka: " << strlen(cid) << "\n";
}
// this->cid = "9f544930303030300000000b47015423";
// this->csd = "400e00325b5900003a0d7f800a40008d";
cout << "\n"
<< "CID 2:"
<< " delka: " << strlen(cid) << "\n";
// if (arguments.count("-csd") > 0)
// {
// const int csdLength = arguments["-csd"].length();
// char csdArg[csdLength] = {};
// getCharsFromString(arguments["-csd"], csdArg);
// this->csd = csdArg;
// }
this->licType = 2;
if (arguments.count("-outputType") > 0)
{
if (arguments["-outputType"] == "base64")
this->binaryGeneration = BinaryGenerationType::Base64Cout;
else
this->binaryGeneration = BinaryGenerationType::File;
}
else
this->binaryGeneration = BinaryGenerationType::Base64Cout;
}
PlcLicence::PlcLicence(string cid, string csd, char *stationName, char *switchName, char *licenceType, char *binaryType, const char *dataFileName)
{
this->cidString = cid;
this->csdString = csd;
this->stationName = stationName;
this->distributor = switchName;
this->dataFileName = dataFileName;
this->licType = 2;
if (binaryType != nullptr)
{
if (binaryType[0] == '1')
this->binaryGeneration = BinaryGenerationType::Base64Cout;
else
this->binaryGeneration = BinaryGenerationType::File;
}
else
this->binaryGeneration = BinaryGenerationType::Base64Cout;
}
void PlcLicence::getSDData()
{
int length = strlen(cid); // Get the length of the char array
for (int i = 0; i < length; i++)
this->sdData.CID_nibble[i] = (BYTE)cid[i];
for (int i = 0; i < cnibblescount / 2; i++)
{
this->sdData.CID[i] = cHexNibble_to_No[this->sdData.CID_nibble[2 * i]] << 4 | cHexNibble_to_No[this->sdData.CID_nibble[2 * i + 1]];
}
this->sdData.manufacturerID = this->sdData.CID[0];
this->sdData.oemID[0] = this->sdData.CID[1];
this->sdData.oemID[1] = this->sdData.CID[2];
this->sdData.name[0] = this->sdData.CID[3];
this->sdData.name[1] = this->sdData.CID[4];
this->sdData.name[2] = this->sdData.CID[5];
this->sdData.name[3] = this->sdData.CID[6];
this->sdData.name[4] = this->sdData.CID[7];
this->sdData.productRevision_hw = cHexNibble_to_No[this->sdData.CID[16]];
this->sdData.productRevision_sw = cHexNibble_to_No[this->sdData.CID[17]];
if (this->sdData.productRevision_sw < 10)
this->sdData.productRevision = (float)this->sdData.productRevision_hw + ((float)this->sdData.productRevision_sw * 0.1);
else
this->sdData.productRevision = (float)this->sdData.productRevision_hw + ((float)this->sdData.productRevision_sw * 0.01);
this->sdData.serialNumber = this->sdData.CID[9] << 24 | this->sdData.CID[10] << 16 | this->sdData.CID[11] << 8 | this->sdData.CID[12];
this->sdData.manufacturerDate_year = cHexNibble_to_No[this->sdData.CID_nibble[27]] * 10 + cHexNibble_to_No[this->sdData.CID_nibble[28]] + 2000;
this->sdData.manufacturerDate_month = cHexNibble_to_No[this->sdData.CID_nibble[29]];
string date = cSDMonthStr[this->sdData.manufacturerDate_month] + std::to_string(this->sdData.manufacturerDate_year);
for (int i = 0; i < date.length(); i++)
this->sdData.manufacturerDate[i] = date[i];
// CSD
length = strlen(csd); // Get the length of the char array
for (int i = 0; i < length; i++)
this->sdData.CSD_nibble[i] = (BYTE)csd[i];
for (int i = 0; i < cnibblescount / 2; i++)
{
//
this->sdData.CSD[i] = cHexNibble_to_No[this->sdData.CSD_nibble[2 * i]] << 4 | cHexNibble_to_No[this->sdData.CSD_nibble[2 * i + 1]];
}
if (this->sdData.CSD_nibble[0] == 0x34)
{
this->sdData.cardSize = this->sdData.CSD[7] << 16 | this->sdData.CSD[8] << 8 | this->sdData.CSD[9];
this->sdData.cardGSize = (this->sdData.cardSize + 1) / 2048;
if (this->sdData.cardSize > 17200) // TODO result.cardSize
{
}
}
BYTE sdCrc = 0;
for (int i = 0; i <= 14; i++)
{
BYTE sdChar = this->sdData.CID[i];
for (int j = 0; j <= 7; j++)
{
sdCrc = sdCrc << 1;
if ((sdChar ^ sdCrc) & 0x80)
sdCrc = sdCrc ^ 0x09;
sdChar = sdChar << 1;
}
sdCrc = sdCrc & 0x7F;
}
this->sdData.CRCOK = ((sdCrc << 1) | 1) == this->sdData.CID[15];
}
PlcLicence::PlcLicence(char *cid, char *csd, string binaryType, string dataFileName)
{
this->cid = cid;
this->csd = csd;
this->stationName = "";
this->distributor = "";
this->licType = 2;
processConfigFile(dataFileName);
if (binaryType == "base64")
this->binaryGeneration = BinaryGenerationType::Base64Cout;
else
this->binaryGeneration = BinaryGenerationType::File;
}
PlcLicence::PlcLicence(char *cid, char *csd, char *stationName, char *switchName, char *licenceType, char *binaryType, const char *dataFileName)
{
this->cid = cid;
this->csd = csd;
this->stationName = stationName;
this->distributor = switchName;
this->dataFileName = dataFileName;
this->licType = 2;
if (binaryType != nullptr)
{
if (binaryType[0] == '1')
this->binaryGeneration = BinaryGenerationType::Base64Cout;
else
this->binaryGeneration = BinaryGenerationType::File;
}
else
this->binaryGeneration = BinaryGenerationType::Base64Cout;
}
void PlcLicence::initCrypto()
{
if (this->licType == cEzLic_p78ou3_IDType_EOVOSV)
{
this->cryptData.aesInitVector[0] = this->sdData.CID[10];
this->cryptData.aesInitVector[1] = this->sdData.CID[12];
this->cryptData.aesInitVector[2] = this->sdData.CID[11];
this->cryptData.aesInitVector[3] = this->sdData.CID[9];
this->cryptData.aesInitVector[4] = this->sdData.CID_nibble[22] - 15;
this->cryptData.aesInitVector[5] = this->sdData.CID_nibble[24] - 15;
this->cryptData.aesInitVector[6] = this->sdData.CID_nibble[25] - 15;
this->cryptData.aesInitVector[7] = this->sdData.CID_nibble[21] - 15;
memcpy(&this->cryptData.aesInitVector[8], &this->cryptData.aesInitVector[0], 8);
this->cryptData.aesKey[0] = this->sdData.CID[12];
this->cryptData.aesKey[1] = this->sdData.CID_nibble[23] - 15;
this->cryptData.aesKey[2] = this->sdData.CID_nibble[25] - 15;
this->cryptData.aesKey[3] = this->sdData.CID[11];
this->cryptData.aesKey[4] = this->sdData.CID[9];
this->cryptData.aesKey[5] = this->sdData.CID_nibble[21] - 15;
this->cryptData.aesKey[6] = 97 + this->sdData.CID[9] % 25;
this->cryptData.aesKey[7] = this->sdData.CID_nibble[22] - 15;
memcpy(&this->cryptData.aesKey[8], &this->cryptData.aesKey[0], 8);
memcpy(&this->cryptData.aesKey[16], &this->cryptData.aesKey[6], 8);
memcpy(&this->cryptData.aesKey[24], &this->cryptData.aesKey[12], 8);
}
}
unsigned char *PlcLicence::getLicenceContent()
{
getSDData();
initCrypto();
// promenne pro praci se soubory a adresari
DWORD sdFileHandle;
DWORD sdDirHandle;
string dirFileName;
string dirFilePath; //: STRING;
string dirInfo; //: DIRECTORY_INFO; - NAJIT
LicenceDataMainELC dataMainToFileELC1; //: tEz_LicenceDataMainELC1; hlavicka urcena pro zapis do souboru - typ ELC1
LicenceData dataToFile; // tEz_LicenceData_10_10;// data urcena pro sifrovani a zapis do soubotu - verze => hlavicka: 1.0, data: 1.0
// pomocne promenne
BYTE dataWriteToFile[cEzLic_p78ou3_maxDataToFile]; // OF BYTE; data zapisovana do souboru
DWORD retDataCount; //: DWORD; // pocty zapisovanych a ctenych dat - navratova hodnota jednotlivych funkci
string licencePostfix; //: STRING; pomocna promenna pro kontrolu postfixu
string mainLicDescription; //: STRING(79); globalni pojmenovani licence v nesifrovane casti licence
UINT freeDataSize; //: UINT; velikost volne citelnych dat v souboru licenci
UINT cryptDataSize; //: UINT; velikost volne cryptovanych dat v souboru licenci
UINT fullDataSize; //: UINT; celkova velikost souboru licenci
USINT generation = 2; //: USINT; verze SW pro licence
PlcData plcData; // = GetPlcData(dataFileName);// "licData.xml");
plcData.licenceName = "Licence";
plcData.licenceType = "1";
plcData.station = stationName; // "Test";
plcData.distributor = distributor; //"RO1";
LicenceSourceData licSourceData;
if (plcData.licenceType == "EOV" || plcData.licenceType == to_string((int)LicenceType::LicenceEov))
{
licSourceData.licType = 0x1AA2; // 6818 ... proč ?
licSourceData.licPostfix = 0;
getCharsFromString(plcData.station, licSourceData.licDescription1);
getCharsFromString(plcData.station, dataToFile.header.licDescription1);
getCharsFromString(plcData.distributor, licSourceData.licDescription2);
getCharsFromString(plcData.distributor, dataToFile.header.licDescription2);
}
LicenceIdent licIdent;
licIdent.licPrefixType = licSourceData.licType >> 12;
licIdent.licHeaderType = licSourceData.licType >> 8 & 0x000F;
licIdent.licDataType = licSourceData.licType >> 4 & 0x000F;
licIdent.licSubType = licIdent.licHeaderType << 8 | licIdent.licHeaderType;
licIdent.licIDType = licSourceData.licType & 0x000F;
if (licSourceData.licPostfix > 9)
licSourceData.licPostfix = 0;
licencePostfix = to_string(licSourceData.licPostfix);
string licenseFileName = getLicenceName(0);
licSourceData.licPostfixIdent = right(licencePostfix, 1);
int sizeOfData = sizeof(dataToFile);
if (licIdent.licHeaderType == cEzLic_p78ou3_HeaderType_10)
{
if (licIdent.licDataType == cEzLic_p78ou3_DataType_10)
{
dataToFile.id.version = 10;
dataToFile.id.cardSize = this->sdData.cardSize;
switch (licIdent.licIDType)
{
case cEzLic_p78ou3_IDType_DDTS:
mainLicDescription = "ddts ";
break;
case cEzLic_p78ou3_IDType_EOVOSV:
mainLicDescription = "eov, osv ";
break;
default:
mainLicDescription = "neznama app ";
}
mainLicDescription += licSourceData.licPostfixIdent;
mainLicDescription += " => ";
dataToFile.header.licVersion = 10;
dataToFile.header.licType = licIdent.licIDType;
dataToFile.header.licDate = getLicDate();
mainLicDescription += dataToFile.header.licDescription1;
mainLicDescription += " [";
mainLicDescription += dataToFile.header.licDescription2;
mainLicDescription += "]";
if (licIdent.licIDType == cEzLic_p78ou3_IDType_EOVOSV)
{
if (generation == 1) // stará verze
{
dataToFile.header.licCount = 1;
dataToFile.items[0].licCount = 65535;
dataToFile.items[0].protoId = cEzLic_p78ou3_CheckLicNumberId_EOV1;
dataToFile.items[0].data1 = cEzLic_p78ou3_CheckLicNumber_EOV1;
}
else
{
dataToFile.header.licCount = 1;
dataToFile.items[1].licCount = 65535;
dataToFile.items[1].protoId = cEzLic_p78ou3_CheckLicNumberId_EOV1;
dataToFile.items[1].data1 = cEzLic_p78ou3_CheckLicNumber_EOV1;
}
}
unsigned char encrypted[10000] = {};
const int s = sizeof(dataToFile);
unsigned char byteArray[s] = {};
memcpy(byteArray, &dataToFile, sizeof(dataToFile));
dataToFile.crc = calculateCRC16(byteArray, s - sizeof(dataToFile.crc)); // 47535 | 884:38382
memcpy(byteArray, &dataToFile, sizeof(dataToFile));
int finalEncryptedLength = encrypt(byteArray, sizeof(dataToFile), this->cryptData.aesKey, this->cryptData.aesInitVector, encrypted);
if (licIdent.licPrefixType == cEzLic_p78ou3_LicPrefixType_ELC1) // typ1 = pouze zasifrovani dat
{
freeDataSize = sizeof(dataMainToFileELC1); // melo by byt 92
if (1) // EzLic_p78ou3_CryptoData.aesRetVal > 0 crypto
{
dataMainToFileELC1.prefix = 0x31434C45;
getCharsFromString(mainLicDescription, dataMainToFileELC1.licHeader.description);
dataMainToFileELC1.licHeader.sizeData = finalEncryptedLength; // sizeof(dataToFile); // 884;
dataMainToFileELC1.licHeader.licType = licIdent.licIDType;
dataMainToFileELC1.licHeader.licSubType = licIdent.licHeaderType << 8 | licIdent.licDataType;
}
}
const int dataMainLength = sizeof(dataMainToFileELC1);
const int dataToFileLength = sizeof(dataToFile);
const int dataEncryptedLength = finalEncryptedLength;
const int totalLength = dataMainLength + dataToFileLength;
const int totalEncryptedLength = dataMainLength + finalEncryptedLength;
unsigned char bdataMainToFileELC1[dataMainLength] = {};
memcpy(bdataMainToFileELC1, &dataMainToFileELC1, dataMainLength);
unsigned char bdataToFile[dataToFileLength] = {};
memcpy(bdataToFile, &dataToFile, dataToFileLength);
unsigned char totalEncryptedArray[totalEncryptedLength] = {};
for (int i = 0; i < dataMainLength; i++)
totalEncryptedArray[i] = bdataMainToFileELC1[i];
for (int i = 0; i < finalEncryptedLength; i++)
totalEncryptedArray[i + dataMainLength] = encrypted[i];
return totalEncryptedArray;
}
}
return nullptr;
}
string PlcLicence::getLicenceName(BYTE licPostfix)
{
string result = "";
char prefixChar = 97;
if (licPostfix > 9) // chyba
{
}
if (licType == LicenceType::LicenceOther)
{
result = "ezlic_";
result += prefixChar + (this->sdData.CID[12] % 25); // 14 OK "v"
result += prefixChar + (this->sdData.CID[10] % 25); // 15 OK "a"
result += prefixChar + (this->sdData.CID_nibble[22] % 25); // 16 OK "x"
result += prefixChar + ((this->sdData.CID_nibble[23] * 2) % 25); // 17 OK "v"
result += prefixChar + (this->sdData.CID_nibble[24] % 25); // 18 not ok ... má být c = 99
result += prefixChar + ((this->sdData.CID_nibble[25] * 3) % 25); // 19 not ok a 112
result += prefixChar + (this->sdData.CID[9] % 25); // 20 OK
result += prefixChar + (this->sdData.CID[11] % 25); // 21 OK
result += prefixChar + (this->sdData.CID[2] % 25); // 22 OK
result += prefixChar + (this->sdData.CID[1] % 25); // 23 OK
result += prefixChar + (this->sdData.CID[3] % 25); // 24 OK
result += ".lic";
}
else
{
result = "ezlic_eovosv" + to_string(licPostfix) + "_";
result += prefixChar + (this->sdData.CID[12] % 25); // 14 OK "v"
result += prefixChar + (this->sdData.CID[10] % 25); // 15 OK "a"
result += prefixChar + (this->sdData.CID_nibble[22] % 25); // 16 OK "x"
result += prefixChar + ((this->sdData.CID_nibble[23] * 2) % 25); // 17 OK "v"
result += prefixChar + (this->sdData.CID_nibble[24] % 25); // 18 not ok ... má být c = 99
result += prefixChar + ((this->sdData.CID_nibble[25] * 3) % 25); // 19 not ok a 112
result += prefixChar + (this->sdData.CID[9] % 25); // 20 OK
result += prefixChar + (this->sdData.CID[11] % 25); // 21 OK
result += prefixChar + (this->sdData.CID[2] % 25); // 22 OK
result += prefixChar + (this->sdData.CID[1] % 25); // 23 OK
result += prefixChar + (this->sdData.CID[3] % 25); // 24 OK
result += ".lic";
}
return result;
}
struct PlcData GetPlcData(const char *dataFileName)
{
PlcData result;
result.plcType = "WAGO";
result.licenceName = "Licence 1";
result.licenceType = "";
result.licenceVersion = "1";
result.station = "";
result.distributor = "";
FILE *fp;
fp = fopen("licData.xml", "r"); // read mode
fseek(fp, 0, SEEK_END); // seek to end of file
int fileSize = ftell(fp); // get current file pointer
fseek(fp, 0, SEEK_SET);
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
int count = 0;
cout << "fileSize:" << fileSize << "\n";
char fileContent[3000];
for (int i = 0; i < fileSize; i++)
{
char c = fgetc(fp);
fileContent[i] = c;
cout << c;
// printf("%c", c);;
count++;
}
fclose(fp);
std::string fileContentStr(fileContent, sizeof(fileContent));
string typeContentString = getXmlContentFromString(fileContentStr, "type");
string nameContentString = getXmlContentFromString(fileContentStr, "name");
string stationContentString = getXmlContentFromString(fileContentStr, "station");
string switchContentString = getXmlContentFromString(fileContentStr, "switchboard");
cout << typeContentString << "\n";
cout << nameContentString << "\n";
cout << stationContentString << "\n";
cout << switchContentString << "\n";
if (typeContentString != "")
result.licenceType = typeContentString;
if (nameContentString != "")
result.licenceName = nameContentString;
if (stationContentString != "")
result.station = stationContentString;
if (switchContentString != "")
result.distributor = switchContentString;
return result;
}
bool PlcLicence::CreateLicence()
{
getSDData();
initCrypto();
// promenne pro praci se soubory a adresari
DWORD sdFileHandle;
DWORD sdDirHandle;
string dirFileName;
string dirFilePath;
string dirInfo;
LicenceDataMainELC dataMainToFileELC1; //: tEz_LicenceDataMainELC1; hlavicka urcena pro zapis do souboru - typ ELC1
LicenceData dataToFile; // tEz_LicenceData_10_10; // data urcena pro sifrovani a zapis do soubotu - verze => hlavicka: 1.0, data: 1.0
// pomocne promenne
BYTE dataWriteToFile[cEzLic_p78ou3_maxDataToFile]; // OF BYTE; data zapisovana do souboru
DWORD retDataCount; //: DWORD; pocty zapisovanych a ctenych dat - navratova hodnota jednotlivych funkci
string licencePostfix; //: STRING; pomocna promenna pro kontrolu postfixu
string mainLicDescription; //: STRING(79); globalni pojmenovani licence v nesifrovane casti licence
UINT freeDataSize; //: UINT; velikost volne citelnych dat v souboru licenci
UINT cryptDataSize; //: UINT; velikost volne cryptovanych dat v souboru licenci
UINT fullDataSize; //: UINT; celkova velikost souboru licenci
USINT generation = 2; //: USINT; verze SW pro licence
PlcData plcData;
; // = GetPlcData(dataFileName);// "licData.xml");
plcData.licenceName = "Licence";
plcData.licenceType = "1";
plcData.station = stationName; // "Test";
plcData.distributor = distributor; //"RO1";
LicenceSourceData licSourceData;
if (plcData.licenceType == "EOV" || plcData.licenceType == to_string((int)LicenceType::LicenceEov))
{
licSourceData.licType = 0x1AA2; // 6818 ... proč ?
licSourceData.licPostfix = 0;
getCharsFromString(plcData.station, licSourceData.licDescription1);
getCharsFromString(plcData.station, dataToFile.header.licDescription1);
getCharsFromString(plcData.distributor, licSourceData.licDescription2);
getCharsFromString(plcData.distributor, dataToFile.header.licDescription2);
}
LicenceIdent licIdent;
licIdent.licPrefixType = licSourceData.licType >> 12;
licIdent.licHeaderType = licSourceData.licType >> 8 & 0x000F;
licIdent.licDataType = licSourceData.licType >> 4 & 0x000F;
licIdent.licSubType = licIdent.licHeaderType << 8 | licIdent.licHeaderType;
licIdent.licIDType = licSourceData.licType & 0x000F;
if (licSourceData.licPostfix > 9)
licSourceData.licPostfix = 0;
licencePostfix = to_string(licSourceData.licPostfix);
string licenseFileName = getLicenceName(0);
licSourceData.licPostfixIdent = right(licencePostfix, 1);
int sizeOfData = sizeof(dataToFile);
if (licIdent.licHeaderType == cEzLic_p78ou3_HeaderType_10)
{
if (licIdent.licDataType == cEzLic_p78ou3_DataType_10)
{
dataToFile.id.version = 10;
dataToFile.id.cardSize = this->sdData.cardSize;
switch (licIdent.licIDType)
{
case cEzLic_p78ou3_IDType_DDTS:
mainLicDescription = "ddts ";
break;
case cEzLic_p78ou3_IDType_EOVOSV:
mainLicDescription = "eov, osv ";
break;
default:
mainLicDescription = "neznama app ";
}
mainLicDescription += licSourceData.licPostfixIdent;
mainLicDescription += " => ";
dataToFile.header.licVersion = 10;
dataToFile.header.licType = licIdent.licIDType;
dataToFile.header.licDate = getLicDate();
mainLicDescription += dataToFile.header.licDescription1;
mainLicDescription += " [";
mainLicDescription += dataToFile.header.licDescription2;
mainLicDescription += "]";
if (licIdent.licIDType == cEzLic_p78ou3_IDType_EOVOSV)
{
if (generation == 1) // stará verze
{
dataToFile.header.licCount = 1;
dataToFile.items[0].licCount = 65535;
dataToFile.items[0].protoId = cEzLic_p78ou3_CheckLicNumberId_EOV1;
dataToFile.items[0].data1 = cEzLic_p78ou3_CheckLicNumber_EOV1;
}
else
{
dataToFile.header.licCount = 1;
dataToFile.items[1].licCount = 65535;
dataToFile.items[1].protoId = cEzLic_p78ou3_CheckLicNumberId_EOV1;
dataToFile.items[1].data1 = cEzLic_p78ou3_CheckLicNumber_EOV1;
}
}
unsigned char encrypted[10000] = {};
const int s = sizeof(dataToFile);
unsigned char byteArray[s] = {};
memcpy(byteArray, &dataToFile, sizeof(dataToFile));
dataToFile.crc = calculateCRC16(byteArray, s - sizeof(dataToFile.crc)); // 47535 | 884:38382
memcpy(byteArray, &dataToFile, sizeof(dataToFile));
int finalEncryptedLength = encrypt(byteArray, sizeof(dataToFile), this->cryptData.aesKey, this->cryptData.aesInitVector, encrypted);
if (licIdent.licPrefixType == cEzLic_p78ou3_LicPrefixType_ELC1) // typ1 = pouze zasifrovani dat
{
freeDataSize = sizeof(dataMainToFileELC1); // melo by byt 92
if (1) // EzLic_p78ou3_CryptoData.aesRetVal > 0 crypto
{
dataMainToFileELC1.prefix = 0x31434C45;
getCharsFromString(mainLicDescription, dataMainToFileELC1.licHeader.description);
dataMainToFileELC1.licHeader.sizeData = finalEncryptedLength; // sizeof(dataToFile); // 884;
dataMainToFileELC1.licHeader.licType = licIdent.licIDType;
dataMainToFileELC1.licHeader.licSubType = licIdent.licHeaderType << 8 | licIdent.licDataType;
}
}
const int dataMainLength = sizeof(dataMainToFileELC1);
const int dataToFileLength = sizeof(dataToFile);
const int dataEncryptedLength = finalEncryptedLength;
const int totalLength = dataMainLength + dataToFileLength;
const int totalEncryptedLength = dataMainLength + finalEncryptedLength;
unsigned char bdataMainToFileELC1[dataMainLength] = {};
memcpy(bdataMainToFileELC1, &dataMainToFileELC1, dataMainLength);
unsigned char bdataToFile[dataToFileLength] = {};
memcpy(bdataToFile, &dataToFile, dataToFileLength);
unsigned char totalEncryptedArray[totalEncryptedLength] = {};
for (int i = 0; i < dataMainLength; i++)
totalEncryptedArray[i] = bdataMainToFileELC1[i];
for (int i = 0; i < finalEncryptedLength; i++)
totalEncryptedArray[i + dataMainLength] = encrypted[i];
// char chFileName[licenseFileName.length()];
char licFileNameToSave[licenseFileName.length()] = {};
getCharsFromString(licenseFileName, licFileNameToSave);
int totalFileSize = sizeof(totalEncryptedArray);
if (binaryGeneration == BinaryGenerationType::File)
{
FILE *fileLicence = fopen(licFileNameToSave, "wb");
if (fileLicence)
{
size_t r1 = fwrite(&totalEncryptedArray, sizeof(totalEncryptedArray), 1, fileLicence);
//printf("License binary saved.\n");
fclose(fileLicence);
return true;
}
}
else
{
//cout << "data:text/plain;base64,";
cout << "data:application/octet-stream;base64,";
char encryptedChars[totalFileSize];
for (int i = 0; i < totalFileSize; i++)
encryptedChars[i] = static_cast<signed char>(totalEncryptedArray[i]);
string strToBase = convertToString(encryptedChars, totalFileSize);
string base64Coded = base64_encode_ai(strToBase);
cout << base64Coded << endl;
// string decodedBase64 = base64_decode_ai(base64Coded);
// std::ofstream outputFile("outputLicence.txt", std::ios::out | std::ios::binary);
// if (outputFile.is_open())
// {
// outputFile << decodedBase64;
// outputFile.close();
// std::cout << "File written successfully." << std::endl;
// }
// else { std::cerr << "Unable to open the file." << std::endl; }
return true;
// //file testing
// std::string filename = "source.txt ";
// std::string content;
// std::ifstream inputFile(filename);
// if (inputFile.is_open())
// {
// content.assign((std::istreambuf_iterator<char>(inputFile)), (std::istreambuf_iterator<char>()));
// inputFile.close();
// std::cout << "File content:\n" << content << std::endl;
// }
// else
// {
// std::cerr << "Unable to open the file." << std::endl;
// }
// std::ofstream outputFile("output.txt");
// if (outputFile.is_open())
// {
// string codedBase = base64_decode_ai(content);
// outputFile << "Velikost souboru orig souboru: " << codedBase.length() << "\n" << codedBase;
// outputFile.close();
// std::cout << "File written successfully." << std::endl;
// }
// else { std::cerr << "Unable to open the file." << std::endl; }
}
}
}
return false;
}
bool PlcLicence::ReadLicence(const char *dataFileName, WORD licType, BYTE licPostfix, char *cid, char *csd)
{
FILE *licenceFile;
char ch;
long lSize;
size_t result;
licenceFile = fopen(dataFileName, "rb"); // read mode
fseek(licenceFile, 0, SEEK_END); // seek to end of file
const int size = ftell(licenceFile); // get current file pointer
fseek(licenceFile, 0, SEEK_SET);
if (licenceFile == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
int count = 0;
unsigned char licenceContent[size];
for (int i = 0; i < size; i++)
{
ch = fgetc(licenceFile);
licenceContent[i] = ch;
count++;
}
fclose(licenceFile);
this->cid = cid;
this->csd = csd;
getSDData();
string licFileName = getLicenceName(licPostfix);
LicenceDataMainELC licenceHeader;
LicenceIdent licIdent;
LicenceData licEncryptedData;
memset(&licenceHeader, 0, sizeof(LicenceDataMainELC));
memcpy(&licenceHeader, licenceContent, sizeof(LicenceDataMainELC));
const int sizeOfEncryptedData = size - sizeof(LicenceDataMainELC);
unsigned char encryptedData[sizeOfEncryptedData] = {};
for (int i = 0; i < sizeOfEncryptedData; i++)
encryptedData[i] = licenceContent[i + sizeof(LicenceDataMainELC)];
// original jsou testy na velikost přečteného file, zatím TODO
BYTE prefixType = (int)licenceContent[3] - 0x30;
if (prefixType == PrefixType::ELC1)
{
if (licenceHeader.licHeader.sizeData > 0)
{
licIdent.licIDType = licenceHeader.licHeader.licType;
licIdent.licSubType = licenceHeader.licHeader.licSubType;
if (licenceHeader.licHeader.licSubType == cEzLic_p78ou3_SubType_10_10) // zatim natvrdo
{
initCrypto();
// CryptData cryptData = initCrypto(sdData, licIdent.licIDType);
unsigned char decrypted[2000] = {};
int decrypted_len = decrypt(encryptedData, sizeof(encryptedData), cryptData.aesKey, cryptData.aesInitVector, decrypted);
if (sizeof(licEncryptedData) != decrypted_len)
{
operationErrors = "License size mismatch";
return false;
}
else
{
memset(&licEncryptedData, 0, sizeof(licEncryptedData));
memcpy(&licEncryptedData, decrypted, sizeof(licEncryptedData));
if (licEncryptedData.id.version == cEzLic_p78ou3_HeaderType_10 && licEncryptedData.header.licVersion == cEzLic_p78ou3_HeaderType_10)
{
if (licEncryptedData.header.licType == cEzLic_p78ou3_IDType_EOVOSV)
{
if (licEncryptedData.id.cardSize != sdData.cardSize)
{
operationErrors = "Size card mismatch";
return false;
}
if (licEncryptedData.header.licCount > 0)
{
if (licType == LicenceType::LicenceOther)
{
// TODO stará
}
else
{
// maxLic := MIN(EzLlic_5rq4_DataFromFile_10_10.header.licCount, cEzLic_p78ou3_licMaxCount); ?
int maxLic = min(licEncryptedData.header.licCount, cEzLic_p78ou3_licMaxCount);
for (int i = 1; i < maxLic; i++)
{
if (licEncryptedData.items[i].protoId > 0 || licEncryptedData.items[i].licCount > 0 || licEncryptedData.items[i].data1 > 0)
{
// EzLlic_5rq4_CheckData.LicId[EzLlic_5rq4_DataFromFile_10_10.items[licId].protoId] := licId;
}
else
{
operationErrors = "Licence items mismatch";
return false;
}
}
}
}
else
{
operationErrors = "Size card info mismatch";
return false;
}
}
}
else
{
operationErrors = "Licence mismatch";
return false;
}
}
}
}
else
{
operationErrors = "Licence error";
return false;
}
}
else
{
operationErrors = "Licence error";
return false;
}
cout << "Licence readed: " << size << "\n";
return true;
}

1
src/PlcLicence.d Normal file
View File

@@ -0,0 +1 @@
src/PlcLicence.o: src/PlcLicence.cpp include/plcLicence.h include/utils.h

BIN
src/PlcLicence.o Normal file

Binary file not shown.

8
src/licData.xml Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<data version="1">
<plcType>WAGO</plcType>
<licenceType version="1">EOV_OSV</licenceType>
<licenceName>Licence pro EOV_OSV</licenceName>
<station>ceskatrebova</station>
<distributor>RO1</distributor>
</data>

493
src/notes.txt Normal file
View File

@@ -0,0 +1,493 @@
<?xml version="1.0" encoding="UTF-8" ?>
<data version="1">
<plcType>WAGO</type>
<licenceType version="1">EOV_OSV</licenceType>
<licenceName>Licence pro EOV_OSV</licenceName>
<station>ceskatrebova</station>
<distributor>RO1</distributor>
</data>
map<string, const char*> getArguments(int argc, char *argv[])
{
const char splitChar='=';
map<string, const char*> 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;
char* argValueChar;
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];
}
}
//getCharsFromString(argValue, argValueChar);
const char * chValue = argValue.c_str();
result.insert(make_pair(argName, chValue));
}
return result;
}
-cid=9f544930303030300000000b47015423
-outputType=base64
g++ -Wall -Wextra -g -lssl -lcrypto -w -Iinclude -c -MMD src/CreateLicence.cpp -o src/CreateLicence.o
g++ -Wall -Wextra -g -lssl -lcrypto -w -Iinclude -c -MMD src/PlcLicence.cpp -o src/PlcLicence.o
g++ -Wall -Wextra -g -lssl -lcrypto -w -Iinclude -c -MMD src/utils.cpp -o src/utils.o
g++ -Wall -Wextra -g -lssl -lcrypto -w -Iinclude -o output\main.exe src/CreateLicence.o src/PlcLicence.o src/utils.o -Llib
19 - 110 (n)
20 - 105 (i)
21 - 99 (c)
22 - 101 (e)
23 - 49 (1)
59 - 118 (v)
60 - 97 (a)
61 - 100 (d)
62 - 101 (e)
63 - 99 (c)
59 - 49 (1)
// karta2
// cid = "9f54495344434954615ad803b601714d";
// csd = "400e00325b5900003be77f800a400043";
// karta1
// cid = "9f544953444349546159d803600171fb";
// csd = "400e00325b5900003be77f800a400043";
// CreateLicense(cid, csd, stationName, switchName, "licData.xml");
// if (ReadLicence("ezlic_eovosv0_vaxvcpalxjx.lic", nullptr, LidIdType::EovOsv, 0, cid, csd) == false)
// {
// cout << "Reading error: " << operationErrors << "\n" << endl;
// }
BOOL codesys v C ?
string v codeses v C ? char[] s \0 nebo bez \0
g++ -std=c++17 -Wall -Wextra -g -fdiagnostics-color=always -w -Iinclude -c -MMD src/main.cpp -o src/main.o
g++ -std=c++17 -Wall -Wextra -g -fdiagnostics-color=always -w -Iinclude -c -MMD src/test.cpp -o src/test.o
g++ -std=c++17 -Wall -Wextra -g -fdiagnostics-color=always -w -Iinclude -o output\main.exe src/main.o src/test.o -Llib
Online - Login (wago) / /(admin/wago)
F5 run, F8 stepin
https://172.16.154.3/wbm/#/configuration/ports-and-services/network-services
licDate = D#1970-01-01
DEBUG funkční
------------------------------------------------------------------
FUNCTION fEz_CreateLicenceFile : tEz_LicenceRetData
VAR
(* promenne pro praci se soubory a adresari *)
sdFileHandle: DWORD;
sdDirHandle: DWORD;
dirFileName: STRING;
dirFilePath: STRING;
dirInfo: DIRECTORY_INFO;
dataMainToFileELC1: tEz_LicenceDataMainELC1; (* hlavicka urcena pro zapis do souboru - typ ELC1 *)
dataToFile_10_10: tEz_LicenceData_10_10; (* data urcena pro sifrovani a zapis do soubotu - verze => hlavicka: 1.0, data: 1.0 *)
(* pomocne promenne *)
dataWiteToFile: ARRAY [0..cEzLic_p78ou3_maxDataToFile] OF BYTE; (* data zapisovana do souboru *)
retDataCount: DWORD; (* pocty zapisovanych a ctenych dat - navratova hodnota jednotlivych funkci *)
licencePostfix: STRING; (* pomocna promenna pro kontrolu postfixu *)
mainLicDescription: STRING(79); (* globalni pojmenovani licence v nesifrovane casti licence *)
freeDataSize: UINT; (* velikost volne citelnych dat v souboru licenci *)
cryptDataSize: UINT; (* velikost volne cryptovanych dat v souboru licenci *)
fullDataSize: UINT; (* celkova velikost souboru licenci *)
generation: USINT; (* verze SW pro licence *)
(* testCrypt: ARRAY [0..3] OF BYTE := 116,101,115,116; (* test *) *)
testCrypt: ARRAY [0..4] OF BYTE := 107,117,114,118,97;
encTest: ARRAY [0..100] OF BYTE; (* data zapisovana do souboru *)
testByte: BYTE;
END_VAR
(*
funkce:
- nacte SD kartu a dekoduje informace CID, CSD
- vygeneruje jmena a hesla
- vytvori soubor licence
*)
fEz_CreateLicenceFile.isDone := FALSE;
(* nacteni CID a CSD informaci SD karty - pro vsechny verze licencnich souboru STEJNE *)
fEz_CreateLicenceFile := fEz_ReadSD( cEzLic_p78ou3_sdinfofilepath );
IF fEz_CreateLicenceFile.retCode > 0 THEN
RETURN;
END_IF;
(* nastaveni dat licence *)
EZlic_LicenceIdent.licPrefixType := SHR( EZlic_sourceLicenceData.licType, 12 );
EZlic_LicenceIdent.licHeaderType := ( SHR( EZlic_sourceLicenceData.licType, 8 ) AND 16#000F );
EZlic_LicenceIdent.licDataType := ( SHR( EZlic_sourceLicenceData.licType, 4 ) AND 16#000F );
EZlic_LicenceIdent.licSubType := SHL(EZlic_LicenceIdent.licHeaderType, 8) OR EZlic_LicenceIdent.licDataType;
EZlic_LicenceIdent.licIDType := EZlic_sourceLicenceData.licType AND 16#000F;
(* kontrola a nastaveni postfixu *)
IF EZlic_sourceLicenceData.licPostfix > 9 THEN
EZlic_sourceLicenceData.licPostfix := 0;
END_IF;
licencePostfix := BYTE_TO_STRING( EZlic_sourceLicenceData.licPostfix );
EZlic_sourceLicenceData.licPostfixIdent := RIGHT( licencePostfix, 1 );
(* vygenerovani jmena licencniho souboru *)
fEz_CreateLicenceFile := fEz_GetLicenceFileName( EZlic_LicenceIdent.licIDType, EZlic_sourceLicenceData.licPostfix, EZlic_licenceFilePath, generation);
IF fEz_CreateLicenceFile.retCode > 0 THEN
RETURN;
END_IF;
(* nastaveni dat licence *)
CASE EZlic_LicenceIdent.licHeaderType OF
cEzLic_p78ou3_HeaderType_10: (* hlavicka licence verze 1.0 *)
CASE EZlic_LicenceIdent.licDataType OF
cEzLic_p78ou3_DataType_10: (* verze licencnich dat 1.0 *)
(* hlavicka licence *)
dataToFile_10_10.id.version := 10;
dataToFile_10_10.id.cardSize := EzLic_p78ou3_SD_Data.cardSize;
CASE EZlic_LicenceIdent.licIDType OF
cEzLic_p78ou3_IDType_DDTS: (* ddts *)
mainLicDescription := 'ddts ';
cEzLic_p78ou3_IDType_EOVOSV: (* eov, osv *)
mainLicDescription := 'eov, osv ';
ELSE
mainLicDescription := 'neznama app ';
END_CASE;
mainLicDescription := CONCAT( mainLicDescription, EZlic_sourceLicenceData.licPostfixIdent );
mainLicDescription := CONCAT( mainLicDescription, ' => ' );
(* data licence *)
dataToFile_10_10.header.licVersion := 10;
dataToFile_10_10.header.licType := WORD_TO_BYTE( EZlic_LicenceIdent.licIDType );
dataToFile_10_10.header.licDate := DT_TO_DATE( SysRtcGetTime(TRUE) );
dataToFile_10_10.header.licDescription1 := EZlic_sourceLicenceData.licDescription1;
dataToFile_10_10.header.licDescription2 := EZlic_sourceLicenceData.licDescription2;
mainLicDescription := CONCAT( mainLicDescription, dataToFile_10_10.header.licDescription1 );
mainLicDescription := CONCAT( mainLicDescription, ' [' );
mainLicDescription := CONCAT( mainLicDescription, dataToFile_10_10.header.licDescription2 );
mainLicDescription := CONCAT( mainLicDescription, ']' );
CASE EZlic_LicenceIdent.licIDType OF
cEzLic_p78ou3_IDType_EOVOSV: (* eov, osv *)
IF generation = 1 THEN
dataToFile_10_10.header.licCount := 1;
dataToFile_10_10.items[0].licCount := 65535;
dataToFile_10_10.items[0].protoId := cEzLic_p78ou3_CheckLicNumberId_EOV1;
dataToFile_10_10.items[0].data1 := cEzLic_p78ou3_CheckLicNumber_EOV1;
ELSE
dataToFile_10_10.header.licCount := 1;
dataToFile_10_10.items[1].licCount := 65535;
dataToFile_10_10.items[1].protoId := cEzLic_p78ou3_CheckLicNumberId_EOV1;
dataToFile_10_10.items[1].data1 := cEzLic_p78ou3_CheckLicNumber_EOV1;
END_IF;
END_CASE;
(* parametry pro sifrovani a zapis do souboru *)
(* - dekoment
EzLic_p78ou3_CryptoData.cryptDataAddress := ADR( dataToFile_10_10 );
EzLic_p78ou3_CryptoData.cryptDataSize := SIZEOF( dataToFile_10_10 );
*)
EzLic_p78ou3_CryptoData.cryptDataAddress := ADR( testCrypt );
EzLic_p78ou3_CryptoData.cryptDataSize := SIZEOF( testCrypt );
(*nastaveni id souboru a vypocet CRC pro hlavicky a licencnich dat *)
dataToFile_10_10.id.version := 10;
dataToFile_10_10.crc := fEz_crc16( ADR( dataToFile_10_10 ), SIZEOF( dataToFile_10_10 ) - SIZEOF( dataToFile_10_10.crc ) );
dataToFile_10_10.crc := 1000;
ELSE
(* neznama verze licencnich dat *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_data, 1);
RETURN;
END_CASE;
ELSE
(* neznama verze hlavicky kriptovanych dat *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_header, 1);
RETURN;
END_CASE;
(* inicializace Ckryptovacich algoritmu, Vektoru a klice *)
fEz_CreateLicenceFile := fEz_InitCrypto(EZlic_LicenceIdent.licIDType);
IF fEz_CreateLicenceFile.retCode > 0 THEN
RETURN;
END_IF;
(* zpracovani dat licencniho souboru [sifrovani, podpis, komprese, ...] *)
CASE EZlic_LicenceIdent.licPrefixType OF
cEzLic_p78ou3_LicPrefixType_ELC1: (* typ1 = pouze zasifrovani dat *)
freeDataSize := SIZEOF( dataMainToFileELC1 );
EzLic_p78ou3_CryptoData.aesRetVal := WCRYPTO_fAesEncrypt(
pabPlain := EzLic_p78ou3_CryptoData.cryptDataAddress,
diPlainLen := EzLic_p78ou3_CryptoData.cryptDataSize,
sCipher := cEzLic_p78ou3_CipherAES,
pIv := ADR(EzLic_p78ou3_CryptoData.aesInitVector),
diIvLen := SIZEOF(EzLic_p78ou3_CryptoData.aesInitVector),
pKey := ADR(EzLic_p78ou3_CryptoData.aesKey),
diKeyLen := SIZEOF(EzLic_p78ou3_CryptoData.aesKey),
(*
pabCiphered := ADR(encTest),
diCipheredLen := SIZEOF(encTest)
*)
pabCiphered := ADR( dataWiteToFile ) + freeDataSize,
diCipheredLen := SIZEOF( dataWiteToFile ) - freeDataSize
);
(* EzLic_p78ou3_CryptoData.aesRetVal := SIZEOF(dataToFile_10_10); *)
IF EzLic_p78ou3_CryptoData.aesRetVal > 0 THEN
SysMemSet( ADR( dataMainToFileELC1.licHeader.description ), 0, SIZEOF( dataMainToFileELC1.licHeader.description ) );
dataMainToFileELC1.prefix := 16#31434C45;
SysMemCpy( ADR( dataMainToFileELC1.licHeader.description ), ADR( mainLicDescription ), LEN( mainLicDescription ) );
dataMainToFileELC1.licHeader.sizeData := EzLic_p78ou3_CryptoData.aesRetVal;
dataMainToFileELC1.licHeader.licType := WORD_TO_BYTE( EZlic_LicenceIdent.licIDType );
dataMainToFileELC1.licHeader.licSubType := SHL( EZlic_LicenceIdent.licHeaderType, 8 ) OR EZlic_LicenceIdent.licDataType;
SysMemCpy(ADR( dataWiteToFile ), ADR( dataMainToFileELC1 ), freeDataSize );
(* SysMemCpy(ADR(dataWiteToFile) + freeDataSize, ADR(encTest), SIZEOF(encTest)); *)
SysMemCpy(ADR(dataWiteToFile) + freeDataSize, ADR( dataToFile_10_10), SIZEOF( dataToFile_10_10));
cryptDataSize := DINT_TO_UINT( EzLic_p78ou3_CryptoData.aesRetVal );
ELSE
(* chyba pri sifrovani *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_crypto, EzLic_p78ou3_CryptoData.aesRetVal);
RETURN;
END_IF;
ELSE
(* neznamy prefix licencniho souboru *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_prefix, 1);
RETURN;
END_CASE;
IF EZlic_sourceLicenceData.enInit THEN
(* smazani vsech souboru v adresari licenci - pro vsechny verze licencnich souboru STEJNE *)
sdDirHandle := SysDirOpen( EzLic_p78ou3_licencfilepath );
WHILE SysDirRead(sdDirHandle, dirFileName, ADR( dirInfo ) ) > 0 DO
IF NOT dirInfo.bDirectory THEN
dirFilePath := CONCAT( EzLic_p78ou3_licencfilepath, dirFileName );
SysFileDelete( dirFilePath );
END_IF;
END_WHILE;
ELSE
(* smazani pouze aktualini licence *)
SysFileDelete( EZlic_licenceFilePath );
END_IF;
(* zapsani souboru licence na SD kartu - pro vsechny verze licencnich souboru STEJNE *)
fullDataSize := freeDataSize + cryptDataSize;
sdFileHandle := SysFileOpen( EZlic_licenceFilePath, 'w');
IF sdFileHandle > 0 THEN
retDataCount := SysFileWrite( sdfileHandle, ADR( dataWiteToFile ), fullDataSize );
SysFileClose( sdFileHandle );
IF retDataCount <> fullDataSize THEN
(* chyba pri zapisu licence *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_write, 0);
RETURN;
END_IF;
END_IF;
(* korektne vygenerovany soubor licenci *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_no, 0);
fEz_CreateLicenceFile.isDone := TRUE;
---------------------------------------------- funkcni --------------------------------------
(*
funkce:
- nacte SD kartu a dekoduje informace CID, CSD
- vygeneruje jmena a hesla
- vytvori soubor licence
*)
fEz_CreateLicenceFile.isDone := FALSE;
(* nacteni CID a CSD informaci SD karty - pro vsechny verze licencnich souboru STEJNE *)
fEz_CreateLicenceFile := fEz_ReadSD( cEzLic_p78ou3_sdinfofilepath );
IF fEz_CreateLicenceFile.retCode > 0 THEN
RETURN;
END_IF;
(* nastaveni dat licence *)
EZlic_LicenceIdent.licPrefixType := SHR( EZlic_sourceLicenceData.licType, 12 );
EZlic_LicenceIdent.licHeaderType := ( SHR( EZlic_sourceLicenceData.licType, 8 ) AND 16#000F );
EZlic_LicenceIdent.licDataType := ( SHR( EZlic_sourceLicenceData.licType, 4 ) AND 16#000F );
EZlic_LicenceIdent.licSubType := SHL(EZlic_LicenceIdent.licHeaderType, 8) OR EZlic_LicenceIdent.licDataType;
EZlic_LicenceIdent.licIDType := EZlic_sourceLicenceData.licType AND 16#000F;
(* kontrola a nastaveni postfixu *)
IF EZlic_sourceLicenceData.licPostfix > 9 THEN
EZlic_sourceLicenceData.licPostfix := 0;
END_IF;
licencePostfix := BYTE_TO_STRING( EZlic_sourceLicenceData.licPostfix );
EZlic_sourceLicenceData.licPostfixIdent := RIGHT( licencePostfix, 1 );
(* vygenerovani jmena licencniho souboru *)
fEz_CreateLicenceFile := fEz_GetLicenceFileName( EZlic_LicenceIdent.licIDType, EZlic_sourceLicenceData.licPostfix, EZlic_licenceFilePath, generation);
IF fEz_CreateLicenceFile.retCode > 0 THEN
RETURN;
END_IF;
(* nastaveni dat licence *)
CASE EZlic_LicenceIdent.licHeaderType OF
cEzLic_p78ou3_HeaderType_10: (* hlavicka licence verze 1.0 *)
CASE EZlic_LicenceIdent.licDataType OF
cEzLic_p78ou3_DataType_10: (* verze licencnich dat 1.0 *)
(* hlavicka licence *)
dataToFile_10_10.id.version := 10;
dataToFile_10_10.id.cardSize := EzLic_p78ou3_SD_Data.cardSize;
CASE EZlic_LicenceIdent.licIDType OF
cEzLic_p78ou3_IDType_DDTS: (* ddts *)
mainLicDescription := 'ddts ';
cEzLic_p78ou3_IDType_EOVOSV: (* eov, osv *)
mainLicDescription := 'eov, osv ';
ELSE
mainLicDescription := 'neznama app ';
END_CASE;
mainLicDescription := CONCAT( mainLicDescription, EZlic_sourceLicenceData.licPostfixIdent );
mainLicDescription := CONCAT( mainLicDescription, ' => ' );
(* data licence *)
dataToFile_10_10.header.licVersion := 10;
dataToFile_10_10.header.licType := WORD_TO_BYTE( EZlic_LicenceIdent.licIDType );
dataToFile_10_10.header.licDate := DT_TO_DATE( SysRtcGetTime(TRUE) );
dataToFile_10_10.header.licDescription1 := EZlic_sourceLicenceData.licDescription1;
dataToFile_10_10.header.licDescription2 := EZlic_sourceLicenceData.licDescription2;
mainLicDescription := CONCAT( mainLicDescription, dataToFile_10_10.header.licDescription1 );
mainLicDescription := CONCAT( mainLicDescription, ' [' );
mainLicDescription := CONCAT( mainLicDescription, dataToFile_10_10.header.licDescription2 );
mainLicDescription := CONCAT( mainLicDescription, ']' );
CASE EZlic_LicenceIdent.licIDType OF
cEzLic_p78ou3_IDType_EOVOSV: (* eov, osv *)
IF generation = 1 THEN
dataToFile_10_10.header.licCount := 1;
dataToFile_10_10.items[0].licCount := 65535;
dataToFile_10_10.items[0].protoId := cEzLic_p78ou3_CheckLicNumberId_EOV1;
dataToFile_10_10.items[0].data1 := cEzLic_p78ou3_CheckLicNumber_EOV1;
ELSE
dataToFile_10_10.header.licCount := 1;
dataToFile_10_10.items[1].licCount := 65535;
dataToFile_10_10.items[1].protoId := cEzLic_p78ou3_CheckLicNumberId_EOV1;
dataToFile_10_10.items[1].data1 := cEzLic_p78ou3_CheckLicNumber_EOV1;
END_IF;
END_CASE;
(* parametry pro sifrovani a zapis do souboru *)
EzLic_p78ou3_CryptoData.cryptDataAddress := ADR( dataToFile_10_10 );
EzLic_p78ou3_CryptoData.cryptDataSize := SIZEOF( dataToFile_10_10 );
(*nastaveni id souboru a vypocet CRC pro hlavicky a licencnich dat *)
dataToFile_10_10.id.version := 10;
dataToFile_10_10.crc := fEz_crc16( ADR( dataToFile_10_10 ), SIZEOF( dataToFile_10_10 ) - SIZEOF( dataToFile_10_10.crc ) );
ELSE
(* neznama verze licencnich dat *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_data, 1);
RETURN;
END_CASE;
ELSE
(* neznama verze hlavicky kriptovanych dat *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_header, 1);
RETURN;
END_CASE;
(* inicializace Ckryptovacich algoritmu, Vektoru a klice *)
fEz_CreateLicenceFile := fEz_InitCrypto(EZlic_LicenceIdent.licIDType);
IF fEz_CreateLicenceFile.retCode > 0 THEN
RETURN;
END_IF;
(* zpracovani dat licencniho souboru [sifrovani, podpis, komprese, ...] *)
CASE EZlic_LicenceIdent.licPrefixType OF
cEzLic_p78ou3_LicPrefixType_ELC1: (* typ1 = pouze zasifrovani dat *)
freeDataSize := SIZEOF( dataMainToFileELC1 );
EzLic_p78ou3_CryptoData.aesRetVal := WCRYPTO_fAesEncrypt(
pabPlain := EzLic_p78ou3_CryptoData.cryptDataAddress,
diPlainLen := EzLic_p78ou3_CryptoData.cryptDataSize,
sCipher := cEzLic_p78ou3_CipherAES,
pIv := ADR(EzLic_p78ou3_CryptoData.aesInitVector),
diIvLen := SIZEOF(EzLic_p78ou3_CryptoData.aesInitVector),
pKey := ADR(EzLic_p78ou3_CryptoData.aesKey),
diKeyLen := SIZEOF(EzLic_p78ou3_CryptoData.aesKey),
pabCiphered := ADR( dataWiteToFile ) + freeDataSize,
diCipheredLen := SIZEOF( dataWiteToFile ) - freeDataSize );
IF EzLic_p78ou3_CryptoData.aesRetVal > 0 THEN
SysMemSet( ADR( dataMainToFileELC1.licHeader.description ), 0, SIZEOF( dataMainToFileELC1.licHeader.description ) );
dataMainToFileELC1.prefix := 16#31434C45;
SysMemCpy( ADR( dataMainToFileELC1.licHeader.description ), ADR( mainLicDescription ), LEN( mainLicDescription ) );
dataMainToFileELC1.licHeader.sizeData := EzLic_p78ou3_CryptoData.aesRetVal;
dataMainToFileELC1.licHeader.licType := WORD_TO_BYTE( EZlic_LicenceIdent.licIDType );
dataMainToFileELC1.licHeader.licSubType := SHL( EZlic_LicenceIdent.licHeaderType, 8 ) OR EZlic_LicenceIdent.licDataType;
SysMemCpy(ADR( dataWiteToFile ), ADR( dataMainToFileELC1 ), freeDataSize );
cryptDataSize := DINT_TO_UINT( EzLic_p78ou3_CryptoData.aesRetVal );
ELSE
(* chyba pri sifrovani *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_crypto, EzLic_p78ou3_CryptoData.aesRetVal);
RETURN;
END_IF;
ELSE
(* neznamy prefix licencniho souboru *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_prefix, 1);
RETURN;
END_CASE;
IF EZlic_sourceLicenceData.enInit THEN
(* smazani vsech souboru v adresari licenci - pro vsechny verze licencnich souboru STEJNE *)
sdDirHandle := SysDirOpen( EzLic_p78ou3_licencfilepath );
WHILE SysDirRead(sdDirHandle, dirFileName, ADR( dirInfo ) ) > 0 DO
IF NOT dirInfo.bDirectory THEN
dirFilePath := CONCAT( EzLic_p78ou3_licencfilepath, dirFileName );
SysFileDelete( dirFilePath );
END_IF;
END_WHILE;
ELSE
(* smazani pouze aktualini licence *)
SysFileDelete( EZlic_licenceFilePath );
END_IF;
(* zapsani souboru licence na SD kartu - pro vsechny verze licencnich souboru STEJNE *)
fullDataSize := freeDataSize + cryptDataSize;
sdFileHandle := SysFileOpen( EZlic_licenceFilePath, 'w');
IF sdFileHandle > 0 THEN
retDataCount := SysFileWrite( sdfileHandle, ADR( dataWiteToFile ), fullDataSize );
SysFileClose( sdFileHandle );
IF retDataCount <> fullDataSize THEN
(* chyba pri zapisu licence *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_write, 0);
RETURN;
END_IF;
END_IF;
(* korektne vygenerovany soubor licenci *)
fEz_CreateLicenceFile := fEz_SetRetData(cEzLic_p78ou3_error_no, 0);
fEz_CreateLicenceFile.isDone := TRUE;
----------------------------------------------------

791
src/utils.cpp Normal file
View File

@@ -0,0 +1,791 @@
#include <iostream>
#include <stdint.h>
#include <vector>
#include <wchar.h>
#include <cstring>
#include <ctime>
#include <chrono>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <codecvt>
#include <map>
// #include <openssl/evp.h>
// #include <openssl/aes.h>
#include <openssl/conf.h>
#include <openssl/err.h> /* errors */
#include <openssl/ssl.h> /* core library */
// #include <openssl/sha.h>
#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 TestFunction(int i)
{
std::cout << i << "\n";
std::cout << i + 1 << "\n";
}
void generatePause()
{
cin.get();
// system("pause");
}
string getXmlContentFromString(string source, string xmlTag)
{
int xmlTagSize = xmlTag.length();
int keyIndexStart = source.find("<" + xmlTag + ">");
int keyIndexEnd = source.find("</" + xmlTag + ">");
std::string keyContentString = source.substr(keyIndexStart + xmlTagSize + 2, (keyIndexEnd - keyIndexStart - xmlTagSize - 2));
return keyContentString;
}
string getString(unsigned char *charArray)
{
std::string fileContent(reinterpret_cast<char *>(charArray), sizeof(charArray));
return fileContent;
}
void getCharsFromString1(string source, char *charArray)
{
memset(charArray, 0, sizeof(charArray));
int length = source.length(); // Length of the string (excluding null character)
// charArray[length]; // Character array to store the string
for (int i = 0; i < length; i++)
{
charArray[i] = source[i];
}
}
void getCharsFromString(string source, char *charArray)
{
memset(charArray, 0, sizeof(charArray));
int length = source.length(); // Length of the string (excluding null character)
// charArray[length]; // Character array to store the string
for (int i = 0; i < length; i++)
{
charArray[i] = source[i];
}
}
float byteArrayToFloat(const BYTE *byteArray)
{
// Ensure that the byte array has at least 4 elements (32 bits)
if (byteArray == NULL)
{
// Handle error: The pointer is NULL
return 0.0f; // or any appropriate error handling
}
int sizeArray = sizeof(byteArray);
// Interpret the byte array as a 32-bit floating-point value
uint32_t intValue = 0;
if (sizeArray > 0)
intValue |= ((uint32_t)byteArray[0] << 24);
if (sizeArray > 1)
intValue |= ((uint32_t)byteArray[1] << 16);
if (sizeArray > 2)
intValue |= ((uint32_t)byteArray[2] << 8);
if (sizeArray > 0)
intValue |= byteArray[3];
// Typecast the integer representation to a float
float floatValue;
memcpy(&floatValue, &intValue, sizeof(float));
return floatValue;
}
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);
}
std::tm dt_to_date(const std::chrono::system_clock::time_point &tp)
{
std::time_t time = std::chrono::system_clock::to_time_t(tp);
return *std::localtime(&time);
}
std::string parseCID(const std::string &cidHex)
{
// Convert hexadecimal string to binary string
std::string cidBinary;
for (char c : cidHex)
{
std::string binary = "0000";
int val;
if (c >= '0' && c <= '9')
{
val = c - '0';
}
else if (c >= 'a' && c <= 'f')
{
val = c - 'a' + 10;
}
else if (c >= 'A' && c <= 'F')
{
val = c - 'A' + 10;
}
else
{
continue; // Ignore non-hex characters
}
for (int i = 3; i >= 0; --i)
{
binary[i] = '0' + (val & 1);
val >>= 1;
}
cidBinary += binary;
}
// Define the length of individual fields in the CID
const int lengths[] = {8, 16, 40, 8, 32, 12, 7, 4};
const char *fields[] = {"MID", "OID", "PNM", "PRV", "PSN", "MDT", "CRC", "unused"};
// Parse the binary string and print individual fields
int pos = 0;
for (int i = 0; i < 8; ++i)
{
std::string fieldData = cidBinary.substr(pos, lengths[i]);
std::cout << fields[i] << ": " << fieldData << std::endl;
pos += lengths[i];
}
return cidBinary; // Optionally, you can return the full binary string
}
void bitsToCharArray(const std::string &bitsStr, char *charArray)
{
int bitsLen = bitsStr.length();
int charArraySize = bitsLen / 8; // Assuming bitsStr.length() is a multiple of 8
for (int i = 0; i < charArraySize; i++)
{
std::string byteStr = bitsStr.substr(i * 8, 8);
charArray[i] = std::bitset<8>(byteStr).to_ulong();
}
}
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;
}
void wordToByteArray(uint16_t wordValue, uint8_t byteArray[2])
{
byteArray[0] = static_cast<uint8_t>(wordValue & 0xFF); // Low byte
byteArray[1] = static_cast<uint8_t>((wordValue >> 8) & 0xFF); // High byte
}
uint16_t calculateCrc(const uint8_t *data, size_t length)
{
uint16_t crc = 0xFFFF;
uint16_t makeData = 0;
uint16_t cCrcTable[] = {0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040};
uint8_t byteArray[2];
for (int i = 0; i < length; i++)
{
// wordToByteArray(crc, byteArray);
makeData = data[i] ^ (crc);
crc = crc >> 8;
crc = crc ^ cCrcTable[i];
data = data + 1;
}
/* orig
crc := 16#FFFF;
FOR i := 0 TO dataLen - 1 DO
makeData := data^ XOR WORD_TO_BYTE( crc );
crc := SHR( crc, 8 );
crc := crc XOR cCrcTable[makeData];
data := data + 1;
END_FOR;
fEz_crc16 := crc;
*/
return crc;
}
void showCurrentTime()
{
std::time_t now = std::time(nullptr);
std::cout << "Current time (ctime): " << std::ctime(&now);
// Using chrono to get the current time
auto currentTime = std::chrono::system_clock::now();
std::time_t currentTimeT = std::chrono::system_clock::to_time_t(currentTime);
std::cout << "Current time (chrono): " << std::ctime(&currentTimeT);
}
WORD getCurrentDateAsCODESYSDate()
{
/*
Bits 0-4: Day (1 to 31)
Bits 5-8: Month (1 to 12)
Bits 9-15: Year (0 to 127, where 0 represents the year 1984)
date: 2023-07-21 = 0x0A17 ?
daatum: 060: 80 F9 C6 64
*/
std::time_t currentTime = std::time(nullptr);
std::tm *currentTm = std::localtime(&currentTime);
int year = currentTm->tm_year + 1900; // tm_year represents years since 1900
int month = currentTm->tm_mon + 1; // tm_mon represents months from 0 to 11
int day = currentTm->tm_mday;
uint16_t codesysDate = (static_cast<uint16_t>(year - 1984) << 9) | (static_cast<uint16_t>(month) << 5) | static_cast<uint16_t>(day);
return codesysDate;
}
DWORD getCurrentDateAsCODESYSDateDword()
{
std::time_t currentTime = std::time(nullptr);
std::tm *currentTm = std::localtime(&currentTime);
int year = currentTm->tm_year + 1900; // tm_year represents years since 1900
int month = currentTm->tm_mon + 1; // tm_mon represents months from 0 to 11
int day = currentTm->tm_mday;
DWORD codesysDate = (static_cast<uint16_t>(year - 1984) << 9) | (static_cast<uint16_t>(month) << 5) | static_cast<uint16_t>(day);
return codesysDate;
}
uint16_t convertToCODESYSDate(int day, int month, int year)
{
return (static_cast<uint16_t>(year - 1984) << 9) | (static_cast<uint16_t>(month) << 5) | static_cast<uint16_t>(day);
}
uint16_t convertToCODESYSTime(int hour, int minute)
{
return (static_cast<uint16_t>(hour) << 11) | (static_cast<uint16_t>(minute) << 5);
}
DateAndTime getCurrentDateTimeAsCODESYSDateTime()
{
std::time_t currentTime = std::time(nullptr);
std::tm *currentTm = std::localtime(&currentTime);
int year = currentTm->tm_year + 1900; // tm_year represents years since 1900
int month = currentTm->tm_mon + 1; // tm_mon represents months from 0 to 11
int day = currentTm->tm_mday;
int hour = currentTm->tm_hour;
int minute = currentTm->tm_min;
int second = currentTm->tm_sec;
uint16_t codesysDate = (static_cast<uint16_t>(year - 1984) << 9) | (static_cast<uint16_t>(month) << 5) | static_cast<uint16_t>(day);
uint16_t codesysTime = (static_cast<uint16_t>(hour) << 11) | (static_cast<uint16_t>(minute) << 5) | (static_cast<uint16_t>(second) >> 1);
DateAndTime codesysDateTime = {codesysDate, codesysTime};
return codesysDateTime;
}
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;
DATE dateOnly = ttime - totalSeconds + 7200; // 7200 + vteřina za dvě hodiny pro srování
return dateOnly;
}
std::vector<unsigned char> aes256_cbc_encrypt(const std::vector<unsigned char> &plaintext, const std::vector<unsigned char> &key, const std::vector<unsigned char> &iv)
{
std::vector<unsigned char> ciphertext;
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key.data(), iv.data());
int ciphertext_len;
int len;
int max_chunk_size = EVP_CIPHER_block_size(EVP_aes_256_cbc());
ciphertext.resize(plaintext.size() + max_chunk_size);
EVP_EncryptUpdate(ctx, ciphertext.data(), &len, plaintext.data(), plaintext.size());
ciphertext_len = len;
EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len);
ciphertext_len += len;
EVP_CIPHER_CTX_free(ctx);
ciphertext.resize(ciphertext_len);
return ciphertext;
}
void handleErrors(void)
{
ERR_print_errors_fp(stderr);
abort();
}
int encrypt(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()))
handleErrors();
/*
* 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))
handleErrors();
/*
* 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))
handleErrors();
ciphertext_len = len;
/*
* Finalise the encryption. Further ciphertext bytes may be written at
* this stage.
*/
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
handleErrors();
ciphertext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
return ciphertext_len;
}
int decrypt(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()))
handleErrors();
/*
* 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))
handleErrors();
/*
* 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))
handleErrors();
plaintext_len = len;
/*
* Finalise the decryption. Further plaintext bytes may be written at
* this stage.
*/
if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len))
handleErrors();
plaintext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
return plaintext_len;
}
bool CompareFiles(const char *fileName, const char *fileName1)
{
FILE *fp1;
FILE *fp2;
fp1 = fopen(fileName, "rb"); // read mode
fseek(fp1, 0, SEEK_END); // seek to end of file
int size1 = ftell(fp1); // get current file pointer
fseek(fp1, 0, SEEK_SET);
fp2 = fopen(fileName1, "rb"); // read mode
fseek(fp2, 0, SEEK_END); // seek to end of file
int size2 = ftell(fp2); // get current file pointer
fseek(fp2, 0, SEEK_SET);
if (fp1 == NULL || fp2 == NULL)
{
while (1)
{
int byte1 = fgetc(fp1);
int byte2 = fgetc(fp2);
if (byte1 == EOF || byte2 == EOF)
{
if (byte1 != byte2)
{
return false; // 1 indicates files are different
}
break;
}
if (byte1 != byte2)
{
return false; // 1 indicates files are different
break;
}
}
}
else
return false;
fclose(fp1);
fclose(fp2);
return true;
}
// 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;
}
void processCharArray(const unsigned char *arr)
{
size_t arraySize = sizeof(arr) / sizeof(arr[0]);
for (size_t i = 0; i < arraySize; ++i)
{
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
std::string base64_encode(const std::string &in)
{
std::string out;
int val = 0, valb = -6;
size_t len = in.length();
unsigned int i = 0;
for (i = 0; i < len; i++)
{
unsigned char c = in[i];
val = (val << 8) + c;
valb += 8;
while (valb >= 0)
{
out.push_back(base64_url_alphabet[(val >> valb) & 0x3F]);
valb -= 6;
}
}
if (valb > -6)
{
out.push_back(base64_url_alphabet[((val << 8) >> (valb + 8)) & 0x3F]);
}
return out;
}
std::string base64_encode_array(const unsigned char *source)
{
size_t arraySize = sizeof(source) / sizeof(source[0]);
std::string out;
int val = 0, valb = -6;
unsigned int i = 0;
for (i = 0; i < arraySize; i++)
{
unsigned char c = source[i];
val = (val << 8) + c;
valb += 8;
while (valb >= 0)
{
out.push_back(base64_url_alphabet[(val >> valb) & 0x3F]);
valb -= 6;
}
}
if (valb > -6)
{
out.push_back(base64_url_alphabet[((val << 8) >> (valb + 8)) & 0x3F]);
}
return out;
}
std::string base64_decode_ai(const std::string &encoded)
{
std::string decoded;
int val = 0, valb = -8;
for (char c : encoded)
{
if (base64_chars.find(c) == std::string::npos)
break;
val = (val << 6) + base64_chars.find(c);
valb += 6;
if (valb >= 0)
{
decoded.push_back(static_cast<unsigned char>((val >> valb) & 0xFF));
valb -= 8;
}
}
return decoded;
}
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;
}
map<string, string> getArguments(int argc, char *argv[])
{
const char splitChar='=';
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;
}
map<string, const char*> mapArguments(int argc, char *argv[])
{
const char splitChar='=';
map<string, const char*> 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;
char* argValueChar;
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];
}
}
//getCharsFromString(argValue, argValueChar);
const char * chValue = argValue.c_str();
result.insert(make_pair(argName, chValue));
}
return result;
}

29
src/utils.d Normal file
View File

@@ -0,0 +1,29 @@
src/utils.o: src/utils.cpp include/openssl/conf.h \
include/openssl/macros.h include/openssl/opensslconf.h \
include/openssl/configuration.h include/openssl/opensslv.h \
include/openssl/bio.h include/openssl/e_os2.h include/openssl/crypto.h \
include/openssl/safestack.h include/openssl/stack.h \
include/openssl/types.h include/openssl/cryptoerr.h \
include/openssl/symhacks.h include/openssl/cryptoerr_legacy.h \
include/openssl/core.h include/openssl/bioerr.h include/openssl/lhash.h \
include/openssl/conferr.h include/openssl/conftypes.h \
include/openssl/err.h include/openssl/ssl.h include/openssl/comp.h \
include/openssl/comperr.h include/openssl/x509.h \
include/openssl/buffer.h include/openssl/buffererr.h \
include/openssl/evp.h include/openssl/core_dispatch.h \
include/openssl/evperr.h include/openssl/params.h include/openssl/bn.h \
include/openssl/bnerr.h include/openssl/objects.h \
include/openssl/obj_mac.h include/openssl/asn1.h \
include/openssl/asn1err.h include/openssl/objectserr.h \
include/openssl/ec.h include/openssl/ecerr.h include/openssl/rsa.h \
include/openssl/rsaerr.h include/openssl/dsa.h include/openssl/dh.h \
include/openssl/dherr.h include/openssl/dsaerr.h include/openssl/sha.h \
include/openssl/x509err.h include/openssl/x509_vfy.h \
include/openssl/pkcs7.h include/openssl/pkcs7err.h \
include/openssl/http.h include/openssl/pem.h include/openssl/pemerr.h \
include/openssl/hmac.h include/openssl/async.h \
include/openssl/asyncerr.h include/openssl/ct.h include/openssl/cterr.h \
include/openssl/sslerr.h include/openssl/sslerr_legacy.h \
include/openssl/prov_ssl.h include/openssl/ssl2.h include/openssl/ssl3.h \
include/openssl/tls1.h include/openssl/dtls1.h include/openssl/srtp.h \
include/utils.h

BIN
src/utils.o Normal file

Binary file not shown.