From 051a13e6979bcf725f0c97549f3a8a971e343114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C5=A0alda?= Date: Wed, 30 Aug 2023 09:15:13 +0200 Subject: [PATCH] clean and hub --- docker/start.sh | 4 +- include/plcLicence.h | 14 ++- src/CreateLicence.cpp | 25 +++-- src/PlcLicence.cpp | 253 +++++++++++++++++++++++++++++++++++------- 4 files changed, 243 insertions(+), 53 deletions(-) diff --git a/docker/start.sh b/docker/start.sh index ab00bee..05c0749 100644 --- a/docker/start.sh +++ b/docker/start.sh @@ -1,7 +1,7 @@ #!/bin/bash chmod 777 output/licenceGenerator -#./output/licenceGenerator -cid=9f544930303030300000000b47015423 -csd=400e00325b5900003a0d7f800a40008d -outputType=file -configFileName=licData.xml +#./output/licenceGenerator -cid=9f544930303030300000000b47015423 -csd=400e00325b5900003a0d7f800a40008d -outputType=file -configFileName=licData.xml -licenceFileName=ezlic_eovosv0_vaxvcpalxjx.lic -licenceVersion=1 -licenceType=EOV_OSV cd output -./licenceGenerator -cid=9f544930303030300000000b47015423 -csd=400e00325b5900003a0d7f800a40008d -outputType=file -configFileName=licData.xml \ No newline at end of file +./licenceGenerator -cid=9f544930303030300000000b47015423 -csd=400e00325b5900003a0d7f800a40008d -outputType=file -configFileName=licData.xml -licenceFileName=ezlic_eovosv0_vaxvcpalxjx.lic -licenceVersion=1 -licenceType=EOV_OSV \ No newline at end of file diff --git a/include/plcLicence.h b/include/plcLicence.h index c113c2d..be1eac1 100644 --- a/include/plcLicence.h +++ b/include/plcLicence.h @@ -221,6 +221,12 @@ private: const char *dataFileName; // name of xml containing data (if not taken from commandline) WORD licType = 2; // type of licence BinaryGenerationType binaryGeneration = BinaryGenerationType::Base64Cout; //typ generování binárního souboru + + string dataLicenceType = ""; //type of licence from xmlFile; + string dataLicenceVersion = ""; //version type of licence from xmlFile; + string dataCryptoVersion = ""; //version of crypting from xmlFile + string dataGenerationType = ""; //version of dataGeneration from xmlFile + string dataLicenceDataFileName = ""; //name of licence file to read CryptData cryptData; // structure for encryp CidData sdData; // data loaded from SD card @@ -228,7 +234,9 @@ private: void processConfigFile(string &dataFileName); //process data from config file void getSDData(); // reads SD card string getLicenceName(BYTE licPostfix); // get proper licencename - void initCrypto(); // inits keys and vectors for encrypting + void initCrypto(); + bool CreateEosEovLicence(); // create licence for EOV_OSV + bool ReadEosEovLicence(const char *dataFileName); public: string operationErrors = ""; @@ -238,6 +246,10 @@ public: PlcLicence(char *cid, char *csd, string binaryType, string dataFileName); bool CreateLicence(); // creates licence bool ReadLicence(const char *dataFileName, WORD licType, BYTE licPostfix, char *cid, char *csd); // reads licence file to readable structures + bool ReadLicence(const char *dataFileName, string licenceType, string licenceVersion, char *cid, char *csd); + + // bool CreateEosEovLicence(); + }; #endif diff --git a/src/CreateLicence.cpp b/src/CreateLicence.cpp index b7203d0..cb500fe 100644 --- a/src/CreateLicence.cpp +++ b/src/CreateLicence.cpp @@ -3,7 +3,6 @@ #include "utils.h" #include - #define FILEBUFFER 300 #define TWO_HOURSE_SECONDS 7200 @@ -20,22 +19,32 @@ int main(int argc, char *argv[]) const int csdLength = argumentsString["-csd"].length(); char csdArg[32] = {}; getCharsFromString(argumentsString["-csd"], csdArg, csdLength); - + const int cidLength = argumentsString["-cid"].length(); char cidArg[32] = {}; getCharsFromString(argumentsString["-cid"], cidArg, cidLength); - + PlcLicence plcWriteLicence = PlcLicence(cidArg, csdArg, argumentsString["-outputType"], argumentsString["-configFileName"]); if (plcWriteLicence.CreateLicence() == false) { cerr << "Licence creation failed"; } - // PlcLicence plcLicence = PlcLicence(); - // if (plcLicence.ReadLicence("ezlic_eovosv0_vaxvcpalxjx.lic", LidIdType::EovOsv, 0, cidArg, csdArg) == false) - // { - // cout << "Reading error: " << plcLicence.operationErrors << endl; - // } + + /* READ LICENCE CODE + // arguments: -cid, -csd, -licenceFileName, -licenceType=EOV_OSV, -licenceVersion + + PlcLicence plcLicence = PlcLicence(); + const int fileNameLength = argumentsString["-licenceFileName"].length(); + char fileNameArg[fileNameLength] = {}; + getCharsFromString(argumentsString["-licenceFileName"], fileNameArg, fileNameLength); + + if (plcLicence.ReadLicence(fileNameArg, argumentsString["-licenceType"], argumentsString["-licenceVersion"], cidArg, csdArg) == false) + { + cout << "Reading error: " << plcLicence.operationErrors << endl; + } + + */ return EXIT_SUCCESS; } diff --git a/src/PlcLicence.cpp b/src/PlcLicence.cpp index c66c7cd..e39e04b 100644 --- a/src/PlcLicence.cpp +++ b/src/PlcLicence.cpp @@ -51,6 +51,8 @@ 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}; std::string cEzLic_p78ou3_CipherAES = "aes-256-cbc"; // konfigurace kriptovaciho algoritmu +const string eoseovLicenceType = "EOV_OSV"; + PlcLicence::PlcLicence() { } @@ -115,11 +117,12 @@ void PlcLicence::processConfigFile(string &dataFileName) { this->stationName = doc.child("data").child("station").child_value(); this->distributor = doc.child("data").child("distributor").child_value(); - string licType = doc.child("data").child("licenceType").child_value(); - string licVersion = doc.child("data").child("licenceType").attribute("version").value(); - if (licType == "EOV_OSV") this->licType = cEzLic_p78ou3_IDType_EOVOSV;// 1; - // cout << doc.child("data").child("plcType").attribute("t").value() << endl; //přiklad pro atributy - + this->dataLicenceType = doc.child("data").child("licenceType").child_value(); + this->dataLicenceVersion = doc.child("data").child("licenceType").attribute("version").value(); + this->dataGenerationType = this->dataLicenceVersion; + this->dataCryptoVersion = this->dataLicenceVersion; + // if (licType == "EOV_OSV") this->licType = cEzLic_p78ou3_IDType_EOVOSV;// 1; + // cout << doc.child("data").child("plcType").attribute("t").value() << endl; //přiklad pro atributy } else { @@ -199,7 +202,6 @@ void PlcLicence::getSDData() this->sdData.CRCOK = ((sdCrc << 1) | 1) == this->sdData.CID[15]; } - /// @brief inits keys and vectors for encrypting void PlcLicence::initCrypto() { @@ -230,8 +232,8 @@ void PlcLicence::initCrypto() } /// @brief get proper licencename -/// @param licPostfix -/// @return +/// @param licPostfix +/// @return string PlcLicence::getLicenceName(BYTE licPostfix) { string result = ""; @@ -244,39 +246,51 @@ string PlcLicence::getLicenceName(BYTE licPostfix) if (licType == LicenceType::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 += 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 += 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 PlcLicence::CreateLicence() +{ + if (this->dataLicenceType == eoseovLicenceType) + { + return CreateEosEovLicence(); + } + else + { + return false; + } +} + +bool PlcLicence::CreateEosEovLicence() { getSDData(); initCrypto(); @@ -287,8 +301,8 @@ bool PlcLicence::CreateLicence() // pomocne promenne BYTE dataWriteToFile[maxDataToFile]; // OF BYTE; data zapisovana do souboru - string licencePostfix; //: STRING; pomocna promenna pro kontrolu postfixu - string mainLicDescription; //: STRING(79); globalni pojmenovani licence v nesifrovane casti licence + 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 @@ -299,8 +313,8 @@ bool PlcLicence::CreateLicence() PlcData plcData; plcData.licenceName = "Licence"; plcData.licenceType = "1"; - plcData.station = stationName; - plcData.distributor = distributor; + plcData.station = stationName; + plcData.distributor = distributor; LicenceSourceData licSourceData; @@ -462,16 +476,32 @@ bool PlcLicence::CreateLicence() return false; } -bool PlcLicence::ReadLicence(const char *dataFileName, WORD licType, BYTE licPostfix, char *cid, char *csd) +bool PlcLicence::ReadLicence(const char *dataFileName, string licenceType, string licenceVersion, char *cid, char *csd) { + this->cid = cid; + this->csd = csd; + this->dataLicenceType = licenceType; + this->dataLicenceVersion = licenceVersion; + + if (this->dataLicenceType == eoseovLicenceType) + { + return ReadEosEovLicence(dataFileName); + } + + return true; +} + +bool PlcLicence::ReadEosEovLicence(const char *dataFileName) +{ + BYTE licPostfix = 0; FILE *licenceFile; char ch; long lSize; size_t result; - licenceFile = fopen(dataFileName, "rb"); - fseek(licenceFile, 0, SEEK_END); - const int size = ftell(licenceFile); + licenceFile = fopen(dataFileName, "rb"); + fseek(licenceFile, 0, SEEK_END); + const int size = ftell(licenceFile); fseek(licenceFile, 0, SEEK_SET); if (licenceFile == NULL) @@ -493,9 +523,6 @@ bool PlcLicence::ReadLicence(const char *dataFileName, WORD licType, BYTE licPos fclose(licenceFile); - this->cid = cid; - this->csd = csd; - getSDData(); string licFileName = getLicenceName(licPostfix); @@ -509,7 +536,8 @@ bool PlcLicence::ReadLicence(const char *dataFileName, WORD licType, BYTE licPos const int sizeOfEncryptedData = size - sizeof(LicenceDataMainELC); unsigned char encryptedData[sizeOfEncryptedData] = {}; - for (int i = 0; i < sizeOfEncryptedData; i++) encryptedData[i] = licenceContent[i + sizeof(LicenceDataMainELC)]; + for (int i = 0; i < sizeOfEncryptedData; i++) + encryptedData[i] = licenceContent[i + sizeof(LicenceDataMainELC)]; BYTE prefixType = (int)licenceContent[3] - 0x30; if (prefixType == PrefixType::ELC1) @@ -600,3 +628,144 @@ bool PlcLicence::ReadLicence(const char *dataFileName, WORD licType, BYTE licPos cout << "Licence readed: " << size << endl << ", data: " << licenceHeader.licHeader.description << endl; return true; } + +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"); + fseek(licenceFile, 0, SEEK_END); + const int size = ftell(licenceFile); + 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)]; + + 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(); + 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, 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 << endl + << ", data: " << licenceHeader.licHeader.description << endl; + return true; +}