Files
sd_gen/src/PlcLicence.cpp
2023-08-17 14:30:11 +02:00

945 lines
34 KiB
C++

#include <cstring>
#include <fstream>
#include "plcLicence.h"
#include "utils.h"
#define CID_LENGTH 32
#define CSD_LENGTH 32
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 < CID_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
for (int i = 0; i < CSD_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);
cout << licFileNameToSave << endl;
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;
}