608 lines
23 KiB
C++
608 lines
23 KiB
C++
#include <cstring>
|
|
#include <fstream>
|
|
#include <filesystem>
|
|
#include "licenceELC11.h"
|
|
#include "utils.h"
|
|
#include "pugixml.hpp"
|
|
|
|
#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 maxDataToFile = 10000; // velikost datoveho bufferu pro ulozeni dat licence
|
|
|
|
const BYTE 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_IDTypeStrData11[] = {"neznamo", "DDTS", "EOV-OSV", "DRT"};
|
|
const BYTE cnibblescount11 = 32;
|
|
std::string cSDMonthStr11[] = {"-", "I.", "II.", "III.", "IV.", "V.", "VI.", "VII.", "VIII.", "IX.", "X.", "XI.", "XII.", "-", "-", "-"};
|
|
BYTE cHexNibble_to_No11[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 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};
|
|
|
|
const string eoseovLicenceType = "EOV_OSV";
|
|
|
|
LicenceELC11::LicenceELC11()
|
|
{
|
|
}
|
|
|
|
LicenceELC11::LicenceELC11(LicenceIdentification &licIdentification)
|
|
: lIdentification(licIdentification)
|
|
{
|
|
}
|
|
|
|
LicenceELC11::LicenceELC11(string cisArg, string csdArg, string binaryType, string dataFileName)
|
|
{
|
|
|
|
for (unsigned int i = 0; i < cisArg.length(); i++)
|
|
this->cid[i] = cisArg[i];
|
|
for (unsigned int i = 0; i < csdArg.length(); i++)
|
|
this->csd[i] = csdArg[i];
|
|
|
|
this->stationName = "";
|
|
this->distributor = "";
|
|
this->licType = 2;
|
|
|
|
processConfigFile(dataFileName);
|
|
|
|
if (binaryType == "base64")
|
|
this->binaryGeneration = BinaryGenerationType::Base64Cout;
|
|
else
|
|
this->binaryGeneration = BinaryGenerationType::File;
|
|
}
|
|
|
|
/// @brief process config file
|
|
/// @param dataFileName
|
|
void LicenceELC11::processConfigFile(string &dataFileName)
|
|
{
|
|
string fullFile = getCompletePath(dataFileName);
|
|
const int fileNameLength = fullFile.length();
|
|
char fileName[fileNameLength] = {};
|
|
getCharsFromString(fullFile, fileName, fileNameLength);
|
|
|
|
pugi::xml_document doc;
|
|
#ifdef WINDOWS
|
|
pugi::xml_parse_result result = doc.load_file("licData.xml");
|
|
#else
|
|
pugi::xml_parse_result result = doc.load_file(fileName);
|
|
#endif
|
|
|
|
if (result)
|
|
{
|
|
const char *dataRootName = doc.child("data") ? "data" : "licence"; // kompatibilita s verzí, která měla ještě root "data"
|
|
|
|
this->stationName = doc.child(dataRootName).child("station").child_value();
|
|
this->distributor = doc.child(dataRootName).child("distributor").child_value();
|
|
this->dataLicenceType = doc.child(dataRootName).child("licenceType").child_value();
|
|
this->dataLicenceVersion = doc.child(dataRootName).child("licenceType").attribute("version").value();
|
|
this->dataGenerationType = this->dataLicenceVersion;
|
|
this->dataCryptoVersion = this->dataLicenceVersion;
|
|
}
|
|
else
|
|
{
|
|
throw LicenceException((int)51, "Chyba při čtení xml");
|
|
}
|
|
}
|
|
|
|
/// @brief reads data from CID a CSD
|
|
void LicenceELC11::getSDData()
|
|
{
|
|
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_No11[this->sdData.CID_nibble[2 * i]] << 4 | cHexNibble_to_No11[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_No11[this->sdData.CID[16]];
|
|
this->sdData.productRevision_sw = cHexNibble_to_No11[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_No11[this->sdData.CID_nibble[27]] * 10 + cHexNibble_to_No11[this->sdData.CID_nibble[28]] + 2000;
|
|
this->sdData.manufacturerDate_month = cHexNibble_to_No11[this->sdData.CID_nibble[29]];
|
|
string date = cSDMonthStr11[this->sdData.manufacturerDate_month] + std::to_string(this->sdData.manufacturerDate_year);
|
|
|
|
for (unsigned i = 0; i < date.length(); i++)
|
|
this->sdData.manufacturerDate[i] = date[i];
|
|
|
|
// CSD
|
|
for (unsigned int i = 0; i < CSD_LENGTH; i++)
|
|
this->sdData.CSD_nibble[i] = (BYTE)csd[i];
|
|
|
|
for (unsigned int i = 0; i < cnibblescount / 2; i++)
|
|
{
|
|
//
|
|
this->sdData.CSD[i] = cHexNibble_to_No11[this->sdData.CSD_nibble[2 * i]] << 4 | cHexNibble_to_No11[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];
|
|
}
|
|
|
|
/// @brief inits keys and vectors for encrypting
|
|
void LicenceELC11::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);
|
|
}
|
|
}
|
|
|
|
string LicenceELC11::getLicenceName()
|
|
{
|
|
string result = "";
|
|
char prefixChar = 97;
|
|
int licIndex = lIdentification.licenceIndex;
|
|
|
|
// natvrdo, stará ELC
|
|
result = "ezlic_eovosv" + to_string(licIndex) + "_";
|
|
result += prefixChar + (this->sdCard.cardData.CID[12] % 25);
|
|
result += prefixChar + (this->sdCard.cardData.CID[10] % 25);
|
|
result += prefixChar + (this->sdCard.cardData.CID_nibble[22] % 25);
|
|
result += prefixChar + ((this->sdCard.cardData.CID_nibble[23] * 2) % 25);
|
|
result += prefixChar + (this->sdCard.cardData.CID_nibble[24] % 25);
|
|
result += prefixChar + ((this->sdCard.cardData.CID_nibble[25] * 3) % 25);
|
|
result += prefixChar + (this->sdCard.cardData.CID[9] % 25);
|
|
result += prefixChar + (this->sdCard.cardData.CID[11] % 25);
|
|
result += prefixChar + (this->sdCard.cardData.CID[2] % 25);
|
|
result += prefixChar + (this->sdCard.cardData.CID[1] % 25);
|
|
result += prefixChar + (this->sdCard.cardData.CID[3] % 25);
|
|
result += ".lic";
|
|
|
|
return result;
|
|
}
|
|
|
|
/// @brief get proper licencename
|
|
/// @param licPostfix
|
|
/// @return
|
|
string LicenceELC11::getLicenceName(BYTE licPostfix)
|
|
{
|
|
string result = "";
|
|
char prefixChar = 97;
|
|
|
|
if (licPostfix > 9) // chyba
|
|
{
|
|
}
|
|
|
|
if (licType == PlcLicenceType::LicenceOther)
|
|
{
|
|
result = "ezlic_";
|
|
result += prefixChar + (this->sdData.CID[12] % 25);
|
|
result += prefixChar + (this->sdData.CID[10] % 25);
|
|
result += prefixChar + (this->sdData.CID_nibble[22] % 25);
|
|
result += prefixChar + ((this->sdData.CID_nibble[23] * 2) % 25);
|
|
result += prefixChar + (this->sdData.CID_nibble[24] % 25);
|
|
result += prefixChar + ((this->sdData.CID_nibble[25] * 3) % 25);
|
|
result += prefixChar + (this->sdData.CID[9] % 25);
|
|
result += prefixChar + (this->sdData.CID[11] % 25);
|
|
result += prefixChar + (this->sdData.CID[2] % 25);
|
|
result += prefixChar + (this->sdData.CID[1] % 25);
|
|
result += prefixChar + (this->sdData.CID[3] % 25);
|
|
result += ".lic";
|
|
}
|
|
else
|
|
{
|
|
result = "ezlic_eovosv" + to_string(licPostfix) + "_";
|
|
result += prefixChar + (this->sdData.CID[12] % 25);
|
|
result += prefixChar + (this->sdData.CID[10] % 25);
|
|
result += prefixChar + (this->sdData.CID_nibble[22] % 25);
|
|
result += prefixChar + ((this->sdData.CID_nibble[23] * 2) % 25);
|
|
result += prefixChar + (this->sdData.CID_nibble[24] % 25);
|
|
result += prefixChar + ((this->sdData.CID_nibble[25] * 3) % 25);
|
|
result += prefixChar + (this->sdData.CID[9] % 25);
|
|
result += prefixChar + (this->sdData.CID[11] % 25);
|
|
result += prefixChar + (this->sdData.CID[2] % 25);
|
|
result += prefixChar + (this->sdData.CID[1] % 25);
|
|
result += prefixChar + (this->sdData.CID[3] % 25);
|
|
result += ".lic";
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool LicenceELC11::createLicence()
|
|
{
|
|
if (this->dataLicenceType == eoseovLicenceType)
|
|
{
|
|
return createEosEovLicence();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool LicenceELC11::createEosEovLicence()
|
|
{
|
|
getSDData();
|
|
initCrypto();
|
|
|
|
// promenne pro praci se soubory a adresari
|
|
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
|
|
string licencePostfix; //: STRING; pomocna promenna pro kontrolu postfixu
|
|
string mainLicDescription; //: STRING(79); globalni pojmenovani licence v nesifrovane casti licence
|
|
|
|
USINT generation = 2; //: USINT; verze SW pro licenceřř
|
|
|
|
PlcData plcData;
|
|
plcData.licenceName = "Licence";
|
|
plcData.licenceType = "1";
|
|
plcData.station = stationName;
|
|
plcData.distributor = distributor;
|
|
|
|
LicenceSourceData licSourceData;
|
|
|
|
if (plcData.licenceType == "EOV" || plcData.licenceType == to_string((int)PlcLicenceType::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);
|
|
|
|
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(); // 1692230400; //getLicDate(); //1692144000;// 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; // 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
|
|
{
|
|
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 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];
|
|
|
|
string fullFile = getCompletePath(licenseFileName);
|
|
|
|
if (binaryGeneration == BinaryGenerationType::File)
|
|
{
|
|
#ifdef WINDOWS
|
|
|
|
char licFileNameToSave[licenseFileName.length()] = {};
|
|
getCharsFromString(licenseFileName, licFileNameToSave, licenseFileName.length());
|
|
|
|
FILE *fileLicence = fopen(licFileNameToSave, "wb");
|
|
if (fileLicence)
|
|
{
|
|
fwrite(&totalEncryptedArray, sizeof(totalEncryptedArray), 1, fileLicence);
|
|
// printf("License binary saved.\n");
|
|
fclose(fileLicence);
|
|
cout << licenseFileName << endl;
|
|
return true;
|
|
}
|
|
|
|
#else
|
|
std::ofstream outputFile(fullFile);
|
|
if (outputFile.is_open())
|
|
{
|
|
outputFile.write(reinterpret_cast<const char *>(totalEncryptedArray), totalEncryptedLength);
|
|
outputFile.close();
|
|
std::cout << licenseFileName;
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "Unable to open licence file." << std::endl;
|
|
}
|
|
return true;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
int totalFileSize = sizeof(totalEncryptedArray);
|
|
// 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;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool LicenceELC11::readLicence(LicenceInfoGeneral *licences)
|
|
{
|
|
sdCard = SDCard(this->cid_cdsPath);
|
|
if (sdCard.isLoaded == false) throw LicenceException((int)51, "Chyba při čtení SD karty, cesta: " + cid_cdsPath);
|
|
|
|
|
|
for (unsigned int i = 0; i < sdCard.cidString.length(); i++)
|
|
this->cid[i] = sdCard.cidString[i]; // nutné pro původní algoritmus
|
|
for (unsigned int i = 0; i < sdCard.csdString.length(); i++)
|
|
this->csd[i] = sdCard.csdString[i]; // nutné pro původní algoritmus
|
|
|
|
string licFileName = getLicenceName();
|
|
string licFilePath = this->licenceFilePath + licFileName;
|
|
|
|
FILE *licenceFile;
|
|
char ch;
|
|
|
|
const int fileNameLength = licFilePath.length();
|
|
char fileNameCh[fileNameLength] = {};
|
|
for (int i = 0; i < fileNameLength; i++)
|
|
fileNameCh[i] = licFilePath[i];
|
|
|
|
licenceFile = fopen(fileNameCh, "rb"); // read mode
|
|
|
|
if (licenceFile == nullptr)
|
|
throw LicenceException((int)Error11::LicenceReadError, "Licence read error: " + licFilePath);
|
|
|
|
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 (size <= 0)
|
|
throw LicenceException((int)Error11::LicenceReadError, "Licence read error: " + licFilePath);
|
|
|
|
int count = 0;
|
|
|
|
unsigned char licenceContent[size];
|
|
|
|
for (int i = 0; i < size; i++)
|
|
{
|
|
ch = fgetc(licenceFile);
|
|
licenceContent[i] = ch;
|
|
count++;
|
|
}
|
|
|
|
fclose(licenceFile);
|
|
|
|
//getSDData();?
|
|
|
|
LicenceDataMainELC licenceHeader{};
|
|
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)];
|
|
|
|
BYTE prefixType = (int)licenceContent[3] - 0x30;
|
|
if (prefixType == PrefixType::ELC1)
|
|
{
|
|
if (licenceHeader.licHeader.sizeData > 0)
|
|
{
|
|
|
|
if (licenceHeader.licHeader.licSubType == cEzLic_p78ou3_SubType_10_10)
|
|
{
|
|
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)
|
|
{
|
|
throw LicenceException((int)Error11::LicenceSizeMismatch, "License size mismatch ");
|
|
}
|
|
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.header.licCount > 0)
|
|
{
|
|
for (int i = 0; i < licMaxCount; i++)
|
|
{
|
|
licences->licences.insert(pair<int, int>(licEncryptedData.items[i].protoId, licEncryptedData.items[i].licCount));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw LicenceException((int)Error11::LicenceSizeCardMismatch, "Size card info mismatch");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw LicenceException((int)Error11::LicenceMismatch, "Licence mismatch");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw LicenceException((int)Error11::LicenceMismatch, "Licence mismatch");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw LicenceException((int)Error11::LicenceReadError, "Licence error");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
LicenceELC11::~LicenceELC11() {}
|