diff --git a/output/ezlic_drt0_jjacdgpdxpb.lic b/ezlic_drt0_jjacdgpdxpb.lic similarity index 84% rename from output/ezlic_drt0_jjacdgpdxpb.lic rename to ezlic_drt0_jjacdgpdxpb.lic index ab667a0..85143b9 100644 Binary files a/output/ezlic_drt0_jjacdgpdxpb.lic and b/ezlic_drt0_jjacdgpdxpb.lic differ diff --git a/include/common/licenceCommon.h b/include/common/licenceCommon.h index 6dcd04a..c68bf77 100644 --- a/include/common/licenceCommon.h +++ b/include/common/licenceCommon.h @@ -52,6 +52,7 @@ enum class GeneralError LicenceSizeCardMismatch = 53, LicenceMismatch = 54, LicenceCRCMismatch = 54, + UIDReadError = 55, ItemsCountMismatch = 61 }; @@ -168,6 +169,13 @@ struct LicenceELC2Info map licences = {}; }; +/* struktury pro ELC 3 */ +// defaultní struktura pro ELC 3 +struct LicenceELC3Info +{ + map licences = {}; +}; + // struct LicenceELC2Info_1 // { // map licences = {}; @@ -180,13 +188,27 @@ struct LicenceELC2Item DWORD dataPointsCount{}; }; -// struktura polozky ELC 2, +// struktura polozky ELC 2 pro další kompatibility struct LicenceELC2Item_1 { DWORD protocolId{}; DWORD dataPointsCount{}; }; +// defaultni struktura polozky ELC 3 +struct LicenceELC3Item +{ + DWORD protocolId{}; + DWORD dataPointsCount{}; +}; + +// struktura polozky ELC 3 pro další kompatibility, +struct LicenceELC3Item_1 +{ + DWORD protocolId{}; + DWORD dataPointsCount{}; +}; + class LicenceException : public std::exception { public: diff --git a/include/common/licenceELC3.h b/include/common/licenceELC3.h new file mode 100644 index 0000000..4e6f90a --- /dev/null +++ b/include/common/licenceELC3.h @@ -0,0 +1,89 @@ +#ifndef EZ_APPLICATION_LICENCE_DISABLE + +#ifndef PLC_LICENCE3_COMMON_H +#define PLC_LICENCE3_COMMON_H + +#define UID_LENGTH 32 + +#include +#include "licenceCommon.h" + +/// @brief společná třída pro pro reader i generator licence typu ELC2 +class LicenceELC3 +{ +public: + LicenceELC3(); + LicenceELC3(LicenceIdentification &licIdentification); + ~LicenceELC3(); + + string licenceFilePath = ""; + string licFileName = ""; + string uid = ""; + BYTE uidb[UID_LENGTH] = {}; + string uid_path = ""; ///etc/machine-id + + + Mapping mapping; + + ErrorMessage errorMessage; + + struct LicenceId + { + char licIdent[5] = {'E', 'L', 'C', '0', '_'}; + }; + + // struct __attribute__((__packed__)) LicencePublicHeader + struct LicenceIdentDataHeader + { + BYTE licenceType{}; // EOSEOV, DRT ... + BYTE licenceTypeVersion = 1; // verze licence, urcuje nuance sifrování a pojmenování souborů + BYTE licenceIndex{}; // puvodní post fix, identifikátor pro více licencí + BYTE compatibilityVersion = 1; // udava verzi komplet PrivateContent + BYTE licItemCount{}; // počet protokolů v linenci + WORD publicHeaderLength{}; // délka veřejné hlavičy + // WORD cardSize{}; // velikost SD karty + // DWORD serialNumber = {}; // seriove cislo karty + }; + + struct licDataItem + { + DWORD protoId{}; // id protokolu pro ktery je licence + DWORD licCount{}; // pocet datovych bodu licence + }; + + struct PublicHeader + { + string version = ""; + string projectDescription = ""; + string date = ""; + string licenceType = ""; + }; + + struct PrivateContent // privátní šifrovaná část + { + LicenceIdentDataHeader licenceIdentHeader{}; + vector dataItems{}; + WORD crc{}; + }; + + struct LicenceBody + { + LicenceId licId{}; + LicenceIdentDataHeader licenceIdentHeader{}; + string publicHeader = ""; // JSON + PrivateContent privateContent{}; + }; + +protected: + vector cryptPrivateContent(const std::vector &content); + vector decryptPrivateContent(const std::vector &content); + void initVector(BYTE *iVector, BYTE *key); + string getLicenceName(); + LicenceBody licBody{}; + LicenceIdentification lIdentification{}; + +private: +}; + +#endif +#endif \ No newline at end of file diff --git a/include/generator/licGenELC3.h b/include/generator/licGenELC3.h index 14eb29e..8941e48 100644 --- a/include/generator/licGenELC3.h +++ b/include/generator/licGenELC3.h @@ -1,9 +1,38 @@ -#ifndef ELC3_GENERATOR__H -#define ELC3_GENERATOR__H +#ifndef ELC3_GENERATOR_H +#define ELC3_GENERATOR_H + +#include "utils.h" +#include "licenceCommon.h" +#include "licenceELC3.h" +#include "pugixml.hpp" + +using namespace std; namespace Generator { - + class Licence3 : public LicenceELC3 + { + + public: + Licence3(); + Licence3(string uuid, pugi::xml_document * xmlDoc); + ~Licence3(); + + string cid = ""; + string csd = ""; + pugi::xml_document *xmlDoc; + string projectDescription = ""; + + bool createLicence(); + + private: + void getHeader(); + string getVersion(int middleVersion); + bool processInputConfiguration(); + void getLicenceItems(); + + + }; } #endif \ No newline at end of file diff --git a/include/reader/licReaderELC3.h b/include/reader/licReaderELC3.h index 352c4ef..48fd71d 100644 --- a/include/reader/licReaderELC3.h +++ b/include/reader/licReaderELC3.h @@ -3,9 +3,29 @@ #ifndef ELC3_READER__H #define ELC3_READER__H +#include "utils.h" +#include "licenceCommon.h" +#include "licenceELC3.h" + namespace Reader { - + class Licence3 : public LicenceELC3 + { + public: + LicenceELC3Info licenceInfo; + + Licence3(); + ~Licence3(); + Licence3(LicenceIdentification &licIdentification); + + bool readLicence(LicenceInfoGeneral *licences); + bool getLicenceInfo(void *ptr); + void getLicenceItems(); + + private: + bool getUID(); + + }; } #endif diff --git a/include/reader/licenceReader.h b/include/reader/licenceReader.h index cf3bba2..1e03fb8 100644 --- a/include/reader/licenceReader.h +++ b/include/reader/licenceReader.h @@ -21,6 +21,7 @@ struct InitStructure int compatibility = 0; string licenceFilePath = ""; string cid_csd_filePath = ""; + string uid_filePath = ""; }; /// @brief struktura pro informaci o licenci @@ -49,6 +50,7 @@ public: bool getLicenceItemInfo(int protocolId, void *returnItemStructure); //vrací informace o licenčím bodu na základě id protocolu a předané návratové struktury private: + Licence3 *licence3 {}; //interní struktura pro zpracování licence ELC2 Licence2 *licence2 {}; //interní struktura pro zpracování licence ELC2 Licence1 *licence1 {}; //interní struktura pro zpracování licence ELC1 LicenceIdentification licIdentification {}; diff --git a/output/createnew.bat b/output/createnew.bat index 1fe5acb..2025a9f 100644 --- a/output/createnew.bat +++ b/output/createnew.bat @@ -1 +1 @@ -licenceGenerator.exe -cid=0353445355313647801b1a9f6600c747 -csd=0353445355313647801b1a9f6600c747 -outputType=file -configFileName=licData.xml \ No newline at end of file +licenceGenerator.exe -uid=9a2314bcee131834715adcabc506724c -cid=9f54495344434954615ad803c50171bf -csd=400e00325b5900003be77f800a400043 -outputType=file -configFileName=licData.xml diff --git a/output/createnewELC2.bat b/output/createnewELC2.bat new file mode 100644 index 0000000..d96b191 --- /dev/null +++ b/output/createnewELC2.bat @@ -0,0 +1 @@ +licenceGenerator.exe -cid=9f54495344434954615ad803c50171bf -csd=400e00325b5900003be77f800a400043 -outputType=file -configFileName=licData.xml diff --git a/output/ezlic_drt0_yfavdwbbxbg.lic b/output/ezlic_drt0_yfavdwbbxbg.lic new file mode 100644 index 0000000..f8aa693 Binary files /dev/null and b/output/ezlic_drt0_yfavdwbbxbg.lic differ diff --git a/output/ezlic_eovosv0_wqxcyjpdxji.lic b/output/ezlic_eovosv0_wqxcyjpdxji.lic deleted file mode 100644 index 98d0dd2..0000000 Binary files a/output/ezlic_eovosv0_wqxcyjpdxji.lic and /dev/null differ diff --git a/output/licData.xml b/output/licData.xml index adb5aa9..9bcb75d 100644 --- a/output/licData.xml +++ b/output/licData.xml @@ -1,5 +1,5 @@ - + DRT wago Licence pro EOV_OSV @@ -33,7 +33,7 @@ pt_Ez_iec61850c 7 -77 +30777 \ No newline at end of file diff --git a/output/machine-id b/output/machine-id new file mode 100644 index 0000000..da26398 --- /dev/null +++ b/output/machine-id @@ -0,0 +1 @@ +9a2314bcee131834715adcabc506724c \ No newline at end of file diff --git a/src/CreateLicence.cpp b/src/CreateLicence.cpp index 0ae37a0..5d98fed 100644 --- a/src/CreateLicence.cpp +++ b/src/CreateLicence.cpp @@ -1,15 +1,17 @@ #ifndef EZ_APPLICATION_LICENCE_DISABLE -#define LINUX 1 -//#define WINDOWS 1 +// #define LINUX 1 +#define WINDOWS 1 +#define READ 1 #include #include "licenceGenerator.h" +#include "reader/licenceReader.h" /// @brief hlavní funkce /// @param argc /// @param argv parametry pro generování licence /// @return -int main9(int argc, char *argv[]) +int main(int argc, char *argv[]) { unordered_map arguments = getArguments(argc, argv); try @@ -17,6 +19,47 @@ int main9(int argc, char *argv[]) unordered_map arguments = getArguments(argc, argv); LicenceGenerator generatorOld = LicenceGenerator(arguments["-uid"], arguments["-cid"], arguments["-csd"], arguments["-configFileName"]); generatorOld.createLicenceFile(); + system("pause"); + +#ifdef READ + InitStructure initStructure = {}; + initStructure.licenceType = (int)LicenceType::DRT; + initStructure.licenceVersion = 1; + initStructure.licenceIndex = 0; + initStructure.licenceFilePath = "c://_projects//sd_gen//output//"; // cesta k licenčnímu souboru + // initStructure.compatibility = 0; v případě kompatibility 0 či nezadané je výstup defaultní. + // pro ELC 1 LicenceELC1Info je to isValid, pro ELC 2 strukura { int protocolId = -1; int dataPointsCount = 0; } + initStructure.cid_csd_filePath = ""; // cesta k cidu/csd pro načtení a kontrolu licence + initStructure.uid_filePath = ""; // cesta k souboru machine-id. (/etc/machine-id), takze by mělo být /etc/. machine-id si doplním + + //---------------------------------------- ELC3 ---------------------------------------------------------- + // verze ELC 3 pro jeden protokol. Oproti ELC2 je potřeba přidat cestu k uid/machine-id v initStructure + LicenceReader licenceReaderELC3{}; + if (licenceReaderELC3.initread(3, initStructure)) // iniciacni nacteni + { + LicenceELC3Item info; // podle ELC a kompatibility určit strukuru (LicenceInfo11, LicenceInfo21, LicenceInfo31) + // if () + int protocolId = 7; + // ukazka dat SD karty + cout << "název licenčního souboru: " << licenceReaderELC3.licInfo.licenceFileName << "\n"; + cout << "cesta k licenčnímu souboru: " << licenceReaderELC3.licInfo.licenceFilePath << "\n"; + + if (licenceReaderELC3.getLicenceItemInfo(protocolId, &info)) + { + cout << "Pocet licencních bodu pro " << info.protocolId << ": " << info.dataPointsCount << std::endl; + } + else + cout << "Tento protokol nemá body"; + } + else + { + cout << "CHYBA: " << licenceReaderELC3.error.message; + } + //---------------------------------------- ELC3 ---------------------------------------------------------- + system("pause"); + return SUCCES; +#endif + return SUCCES; } catch (const LicenceException &ex) diff --git a/src/ReadLicence.cpp b/src/ReadLicence.cpp index 6f8ee6b..b073686 100644 --- a/src/ReadLicence.cpp +++ b/src/ReadLicence.cpp @@ -1,7 +1,7 @@ #ifndef EZ_APPLICATION_LICENCE_DISABLE -#define LINUX 1 -// #define WINDOWS 1 +//#define LINUX 1 +#define WINDOWS 1 #include "licenceReader.h" @@ -9,7 +9,7 @@ /// @param argc /// @param argv parametry pro generování licence /// @return -int main() +int main8() { // buffer,850client,104client, 104server, web // kouknout na unikatní klíc pro linux (native uid, i openssl neco má) @@ -24,31 +24,35 @@ int main() // initStructure.compatibility = 0; v případě kompatibility 0 či nezadané je výstup defaultní. // pro ELC 1 LicenceELC1Info je to isValid, pro ELC 2 strukura { int protocolId = -1; int dataPointsCount = 0; } initStructure.cid_csd_filePath = ""; // cesta k cidu/csd pro načtení a kontrolu licence + initStructure.uid_filePath = ""; // cesta k souboru machine-id. (/etc/machine-id), takze by mělo být /etc/. - // // verze původní ELC 1 - // LicenceReader licenceReaderELC1{}; - // if (licenceReaderELC1.initread(1, initStructure)) // iniciacni nacteni - // { - // LicenceELC1Info info; // struktura pro ELC1. Nemá tam asi nic jiného smysl nez true/false - // if (licenceReaderELC1.getLicenceInfo(&info)) - // { - // if (info.isValid) - // cout << "Platna licence ELC1 \n"; - // else - // cout << "Neplatna licence ELC1\n"; - // } - // else - // cout << "CHYBA: " << licenceReaderELC1.error.message; - // } - // else - // { - // cout << "CHYBA: " << licenceReaderELC1.error.message; - // } - // return SUCCES; + //---------------------------------------- ELC3 ---------------------------------------------------------- + //verze ELC 3 pro jeden protokol. Oproti ELC2 je potřeba přidat cestu k uid/machine-id v initStructure + LicenceReader licenceReaderELC3{}; + if (licenceReaderELC3.initread(3, initStructure)) // iniciacni nacteni + { + LicenceELC3Item info; // podle ELC a kompatibility určit strukuru (LicenceInfo11, LicenceInfo21, LicenceInfo31) + // if () + int protocolId = 4; + cout << "název licenčního souboru: " << licenceReaderELC3.licInfo.licenceFileName << "\n"; + cout << "cesta k licenčnímu souboru: " << licenceReaderELC3.licInfo.licenceFilePath << "\n"; - // TODO přidat udaje o SD, kompatibilita, čas, jmeno licenčního souboru - // pročistit private/public + if (licenceReaderELC3.getLicenceItemInfo(protocolId, &info)) + { + cout << "Pocet licencních bodu pro " << info.protocolId << ": " << info.dataPointsCount << std::endl; + } + else + cout << "Tento protokol nemá body"; + } + else + { + cout << "CHYBA: " << licenceReaderELC3.error.message; + } + //---------------------------------------- ELC3 ---------------------------------------------------------- + system("pause"); + return SUCCES; + // verze ELC 2 pro jeden protokol LicenceReader licenceReaderELC2{}; @@ -59,8 +63,8 @@ int main() // Tedy pro ELC1 to bude LicenceELC1_1, pro ELC LicenceELC2_1 LicenceELC2Item info; // podle ELC a kompatibility určit strukuru (LicenceInfo11, LicenceInfo21, LicenceInfo31) // if () - int protocolId = 2; - // ukayka dat SD karty + int protocolId = 4; + // ukazka dat SD karty cout << "SD přečteno: " << licenceReaderELC2.sdCardInfo.isLoaded << "\n"; cout << "Card size: " << licenceReaderELC2.sdCardInfo.cardSize << "\n"; cout << "serial: " << licenceReaderELC2.sdCardInfo.serialNumber << "\n"; @@ -82,7 +86,6 @@ int main() //........... // } - // TODO toto upravit, kdyz nic neexistuje, tak to vrátí false if (licenceReaderELC2.getLicenceItemInfo(protocolId, &info)) { cout << "Pocet licencních bodu pro " << info.protocolId << ": " << info.dataPointsCount << std::endl; @@ -133,6 +136,29 @@ int main() system("pause"); return SUCCES; + + // verze původní ELC 1, zatím zůstává staré řešení + // LicenceReader licenceReaderELC1{}; + // if (licenceReaderELC1.initread(1, initStructure)) // iniciacni nacteni + // { + // LicenceELC1Info info; // struktura pro ELC1. Nemá tam asi nic jiného smysl nez true/false + // if (licenceReaderELC1.getLicenceInfo(&info)) + // { + // if (info.isValid) + // cout << "Platna licence ELC1 \n"; + // else + // cout << "Neplatna licence ELC1\n"; + // } + // else + // cout << "CHYBA: " << licenceReaderELC1.error.message; + // } + // else + // { + // cout << "CHYBA: " << licenceReaderELC1.error.message; + // } + + // return SUCCES; + } // buffer,web, 850client,104client, 104server, diff --git a/src/common/licenceELC2.cpp b/src/common/licenceELC2.cpp index bf86885..f420c94 100644 --- a/src/common/licenceELC2.cpp +++ b/src/common/licenceELC2.cpp @@ -64,8 +64,10 @@ string LicenceELC2::getLicenceName() vector LicenceELC2::cryptPrivateContent(const std::vector &content) { - BYTE initVector[15] = {}; - BYTE aesKey[32] = {}; + // BYTE initVector[15] = {}; old funkční s 15, předěláme to do 16 pro test + // BYTE aesKey[32] = {}; + BYTE initVector[CRYPT_INIT_VECTOR_SIZE] = {0}; + BYTE aesKey[CRYPT_INIT_KEY_SIZE] = {0}; LicenceELC2::initVector(initVector, aesKey); @@ -105,7 +107,6 @@ vector LicenceELC2::decryptPrivateContent(const std::vector res{}; for (int i = 0; i < decrypted_len; i++) { - // if (i==15) res.push_back(1); res.push_back(decrypted[i]); } diff --git a/src/common/licenceELC3.cpp b/src/common/licenceELC3.cpp new file mode 100644 index 0000000..1128f8b --- /dev/null +++ b/src/common/licenceELC3.cpp @@ -0,0 +1,179 @@ +#ifndef EZ_APPLICATION_LICENCE_DISABLE + +#include "licenceELC3.h" +#include "utils.h" + +LicenceELC3::LicenceELC3() {} + +LicenceELC3::~LicenceELC3() {} + +LicenceELC3::LicenceELC3(LicenceIdentification &licIdentification) : lIdentification(licIdentification) +{ +} + +/// @brief get proper licencename +/// @param licPostfix +/// @return +string LicenceELC3::getLicenceName() +{ + + BYTE uidb[UID_LENGTH] = {}; + for (unsigned int i = 0; i < this->uid.length(); i++) uidb[i] = uid[i]; + + string result = ""; + char prefixChar = 97; + int licType = (int)lIdentification.licLicenceType; + int lVersion = lIdentification.licenceVersion; + + unordered_map baseString; + baseString.insert(std::pair((int)LicenceType::EOS_EOV, "ezlic_eovosv")); + baseString.insert(std::pair((int)LicenceType::DDTS, "ezlic_ddts")); + baseString.insert(std::pair((int)LicenceType::DRT, "ezlic_drt")); + + struct Index + { + int index[11]; + }; + + std::unordered_map indexes; + Index indexes1 = {7, 16, 20, 23, 18, 4, 9, 11, 6, 9, 13}; + Index indexes2 = {12, 10, 22, 23, 24, 25, 9, 11, 2, 1, 3}; // puvodní indexy + Index indexes3 = {8, 13, 11, 9, 7, 11, 10, 13, 5, 20, 19}; + + indexes.insert(std::pair(1, indexes1)); + indexes.insert(std::pair(2, indexes2)); + indexes.insert(std::pair(3, indexes3)); + + result = baseString.at(licType) + to_string(lIdentification.licenceIndex) + "_"; + + result += prefixChar + ((uidb[indexes.at(lVersion).index[0]] + (lIdentification.licenceIndex * 11)) % 25); + result += prefixChar + ((uidb[indexes.at(lVersion).index[1]] + (lIdentification.licenceIndex * 39)) % 25); + + result += prefixChar + ((uidb[indexes.at(lVersion).index[2]] + (lIdentification.licenceIndex * 1)) % 25); + result += prefixChar + ((uidb[indexes.at(lVersion).index[3]] * 2) % 25); + result += prefixChar + ((uidb[indexes.at(lVersion).index[4]] + (lIdentification.licenceIndex * 5)) % 25); + result += prefixChar + ((uidb[indexes.at(lVersion).index[5]] * 3) % 25); + + result += prefixChar + ((uidb[indexes.at(lVersion).index[6]] + (lIdentification.licenceIndex * 52)) % 25); + result += prefixChar + ((uidb[indexes.at(lVersion).index[7]] + (lIdentification.licenceIndex * 34)) % 25); + result += prefixChar + ((uidb[indexes.at(lVersion).index[8]] + (lIdentification.licenceIndex * 21)) % 25); + result += prefixChar + ((uidb[indexes.at(lVersion).index[9]] + (lIdentification.licenceIndex * 47)) % 25); + result += prefixChar + ((uidb[indexes.at(lVersion).index[10]] + (lIdentification.licenceIndex * 7)) % 25); + + result += ".lic"; + return result; +} + +vector LicenceELC3::cryptPrivateContent(const std::vector &content) +{ + + BYTE initVector[CRYPT_INIT_VECTOR_SIZE] = {0}; + BYTE aesKey[CRYPT_INIT_KEY_SIZE] = {0}; + + LicenceELC3::initVector(initVector, aesKey); + + unsigned char encrypted[10000] = {}; + const unsigned char *plainTextArray = content.data(); + int finalEncryptedLength = encrypt(plainTextArray, content.size(), aesKey, initVector, encrypted); + + if (finalEncryptedLength <= 0) + throw LicenceException((int)GeneralError::EncryptError, "Chyba při kryptování."); + + std::vector result(encrypted, encrypted + finalEncryptedLength); + + return result; +} + +vector LicenceELC3::decryptPrivateContent(const std::vector &content) +{ + BYTE initVector[CRYPT_INIT_VECTOR_SIZE] = {0}; + BYTE aesKey[CRYPT_INIT_KEY_SIZE] = {0}; + + LicenceELC3::initVector(initVector, aesKey); + + const unsigned char *encryptedData = content.data(); + unsigned char decrypted[10000] = {}; + + int decrypted_len = decrypt(encryptedData, content.size(), aesKey, initVector, decrypted); + if (decrypted_len <= 0) + throw LicenceException((int)GeneralError::DecryptError, "Chyba při dekryptování."); + + vector res{}; + for (int i = 0; i < decrypted_len; i++) + { + res.push_back(decrypted[i]); + } + + return res; + +} + +void LicenceELC3::initVector(BYTE *iVector, BYTE *key) +{ + BYTE uidb[32] = {}; + for (unsigned int i = 0; i < this->uid.length(); i++) uidb[i] = uid[i]; + + CryptInitVector vec1 = {uidb[10], + uidb[12], + uidb[11], + uidb[9], + uidb[22]-6, + uidb[24]-4, + uidb[25]-13, + uidb[21]-9, + 9, 10, 11, 12, 13, 14, 15, 16}; + CryptInitVector vec2 = {5, 1, 3, uidb[9], 4, 12, 13, 17, 9, uidb[24]-15, 2, 23, 17, 13, 4, 3}; + CryptInitVector vec3 = {2, 7, 1, uidb[6], 8, 13, 16, 6, 4, uidb[20]-15, 8, 7, 2, 14, 15, 21}; + + std::unordered_map vectors; + vectors.insert(std::pair(1, vec1)); + vectors.insert(std::pair(2, vec2)); + vectors.insert(std::pair(3, vec3)); + + CryptAesKey key1 = {uidb[12], + uidb[23] - 15, + uidb[25] - 15, + uidb[11], + uidb[9], + uidb[21], + uidb[9] % 25, + uidb[22] - 15, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + CryptAesKey key2 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + CryptAesKey key3 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + + + std::unordered_map keys; + keys.insert(std::pair(1, key1)); + keys.insert(std::pair(2, key2)); + keys.insert(std::pair(3, key3)); + + int lVersion = lIdentification.licenceVersion; + + iVector[0] = vectors.at(lVersion).vec[0]; + iVector[1] = vectors.at(lVersion).vec[1]; + iVector[2] = vectors.at(lVersion).vec[2]; + iVector[3] = vectors.at(lVersion).vec[3]; + iVector[4] = vectors.at(lVersion).vec[4]; + iVector[5] = vectors.at(lVersion).vec[5]; + iVector[6] = vectors.at(lVersion).vec[6]; + iVector[7] = vectors.at(lVersion).vec[7]; + + memcpy(&iVector[8], &iVector[0], 8); + + key[0] = keys.at(lVersion).key[0]; + key[1] = keys.at(lVersion).key[1]; + key[2] = keys.at(lVersion).key[2]; + key[3] = keys.at(lVersion).key[3]; + key[4] = keys.at(lVersion).key[4]; + key[5] = keys.at(lVersion).key[5]; + key[6] = keys.at(lVersion).key[6]; + key[7] = keys.at(lVersion).key[7]; + memcpy(&key[8], &key[0], 8); + memcpy(&key[16], &key[6], 8); + memcpy(&key[24], &key[12], 8); +} + + + +#endif \ No newline at end of file diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 37e4df6..92b657d 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -1,4 +1,6 @@ + #ifndef EZ_APPLICATION_LICENCE_DISABLE +#define WINDOWS 1 #include #include /* core library */ diff --git a/src/generator/LicenceGenerator.cpp b/src/generator/LicenceGenerator.cpp index aca47d7..41448b1 100644 --- a/src/generator/LicenceGenerator.cpp +++ b/src/generator/LicenceGenerator.cpp @@ -6,6 +6,8 @@ #include "pugixml.hpp" #include +#define WINDOWS 1 + LicenceGenerator::LicenceGenerator() { } @@ -13,16 +15,20 @@ LicenceGenerator::LicenceGenerator() LicenceGenerator::LicenceGenerator(string uid, string cid, string csd, string dataFileName) { - if (dataFileName.empty()) throw LicenceException((int)GeneralError::ParamMissing, "Missing par: dataFileName"); + if (dataFileName.empty()) + throw LicenceException((int)GeneralError::ParamMissing, "Missing par: dataFileName"); if (uid.empty() == false) { + if (uid.length() != 32) throw LicenceException((int)GeneralError::IvanlidParam, "UID incorrect size"); this->licData.uid = uid; } else { - if (cid.empty()) throw LicenceException((int)GeneralError::ParamMissing, "Missing par: CID"); - if (csd.empty()) throw LicenceException((int)GeneralError::ParamMissing, "Missing par: CSD"); + if (cid.empty()) + throw LicenceException((int)GeneralError::ParamMissing, "Missing par: CID"); + if (csd.empty()) + throw LicenceException((int)GeneralError::ParamMissing, "Missing par: CSD"); } this->configFileName = dataFileName; @@ -36,57 +42,56 @@ LicenceGenerator::LicenceGenerator(string uid, string cid, string csd, string da bool LicenceGenerator::processInputConfiguration() { - - string fullFile = getCompletePath(this->configFileName); - const int fileNameLength = fullFile.length(); - char fileName[fileNameLength] = {}; - getCharsFromString(fullFile, fileName, fileNameLength); + + string fullFile = getCompletePath(this->configFileName); + const int fileNameLength = fullFile.length(); + char fileName[fileNameLength] = {}; + getCharsFromString(fullFile, fileName, fileNameLength); #ifdef WINDOWS - pugi::xml_parse_result result = doc.load_file("licData.xml"); + pugi::xml_parse_result result = doc.load_file("licData.xml"); #else - pugi::xml_parse_result result = doc.load_file(fileName); + pugi::xml_parse_result result = doc.load_file(fileName); #endif - if (result) + if (result) + { + const char *dataRootName = doc.child("data") ? "data" : "licence"; // kompatibilita s verzí, která měla ještě root "data" + + if (atoi(&doc.child(dataRootName).attribute("xmlVersion").value()[0]) != XML_VERSION) { - const char *dataRootName = doc.child("data") ? "data" : "licence"; // kompatibilita s verzí, která měla ještě root "data" + throw LicenceException((int)GeneralError::IvanlidParam, "Invalid param: XML VERSION"); + } - if (atoi(&doc.child(dataRootName).attribute("xmlVersion").value()[0]) != XML_VERSION) - { - throw LicenceException((int)GeneralError::IvanlidParam, "Invalid param: XML VERSION"); - } + this->licData.doc = &doc; - this->licData.doc = &doc; - - string licType = doc.child(dataRootName).child("licenceType").child_value(); - if (!licType.empty()) - { - this->licIdentification.licLicenceType = mapping.licMapTypes[licType]; // LicenceType::EOS_EOV; - } - else - { - throw LicenceException((int)GeneralError::ParamMissing, "ERROR MISSING licenceType"); - } - - this->licIdentification.licenceVersion = atoi(&doc.child(dataRootName).child("licenceType").attribute("licenceVersion").value()[0]); - this->licIdentification.revision = doc.child(dataRootName).attribute("revision").value()[0]; - this->licIdentification.licenceIndex = atoi(&doc.child(dataRootName).child("licenceType").attribute("licenceIndex").value()[0]); - this->licIdentification.licElcType = (ELCType)atoi(&doc.child(dataRootName).attribute("elc").value()[0]); - - this->licIdentification.licCompatibility = atoi(&doc.child(dataRootName).attribute("compatibility").value()[0]); - - string plcType = doc.child(dataRootName).child("plcType").child_value(); - if (!plcType.empty()) - { - this->licIdentification.licPlcType = mapping.licMapPlcType[plcType]; - } + string licType = doc.child(dataRootName).child("licenceType").child_value(); + if (!licType.empty()) + { + this->licIdentification.licLicenceType = mapping.licMapTypes[licType]; // LicenceType::EOS_EOV; } else { - cout << "file: " << fileName << "\n"; - throw LicenceException((int)GeneralError::FileOpenError, "Unable to open the config file."); + throw LicenceException((int)GeneralError::ParamMissing, "ERROR MISSING licenceType"); } + this->licIdentification.licenceVersion = atoi(&doc.child(dataRootName).child("licenceType").attribute("licenceVersion").value()[0]); + this->licIdentification.revision = doc.child(dataRootName).attribute("revision").value()[0]; + this->licIdentification.licenceIndex = atoi(&doc.child(dataRootName).child("licenceType").attribute("licenceIndex").value()[0]); + this->licIdentification.licElcType = (ELCType)atoi(&doc.child(dataRootName).attribute("elc").value()[0]); + + this->licIdentification.licCompatibility = atoi(&doc.child(dataRootName).attribute("compatibility").value()[0]); + + string plcType = doc.child(dataRootName).child("plcType").child_value(); + if (!plcType.empty()) + { + this->licIdentification.licPlcType = mapping.licMapPlcType[plcType]; + } + } + else + { + cout << "file: " << fileName << "\n"; + throw LicenceException((int)GeneralError::FileOpenError, "Unable to open the config file."); + } return true; } @@ -120,14 +125,13 @@ void LicenceGenerator::createLicenceELC2() { case 1: { - Generator::Licence2 licence = Generator::Licence2(licData.cid,licData.csd,licData.doc); - licence.createLicence(); - break; + Generator::Licence2 licence = Generator::Licence2(licData.cid, licData.csd, licData.doc); + licence.createLicence(); + break; } - default: throw LicenceException((int)GeneralError::CompatibilityTypeNotImplemented, "Compatibility not implemented."); - + default: + throw LicenceException((int)GeneralError::CompatibilityTypeNotImplemented, "Compatibility not implemented."); } - } void LicenceGenerator::createLicenceELC3() @@ -135,10 +139,14 @@ void LicenceGenerator::createLicenceELC3() switch (this->licIdentification.licCompatibility) { case 1: - //LicenceELC31 licence = LicenceELC31(this->licData); - //licence.createLicence(); + { + Generator::Licence3 licence = Generator::Licence3(licData.uid, licData.doc); + licence.createLicence(); break; } + default: + throw LicenceException((int)GeneralError::CompatibilityTypeNotImplemented, "Compatibility not implemented."); + } } LicenceGenerator::~LicenceGenerator() diff --git a/src/generator/licGenELC3.cpp b/src/generator/licGenELC3.cpp index 196b417..2c06b19 100644 --- a/src/generator/licGenELC3.cpp +++ b/src/generator/licGenELC3.cpp @@ -2,7 +2,287 @@ namespace Generator { - + Licence3::Licence3() + { + } + + Licence3::~Licence3() {} + + Licence3::Licence3(string uid, pugi::xml_document *xmlDoc) + { + this->uid = uid; + + this->xmlDoc = xmlDoc; + if (processInputConfiguration() == false) + throw LicenceException((int)GeneralError::LicenceReadError, "Chyba při čtení licence"); + } + + void Licence3::getHeader() + { + PublicHeader publicHeader; + publicHeader.version = getVersion(lIdentification.revision); + publicHeader.projectDescription = projectDescription; + publicHeader.date = getDate(); + publicHeader.licenceType = lIdentification.licTypeName; + publicHeader.licenceType += to_string(lIdentification.licenceIndex); + + licBody.publicHeader = ""; + + licBody.publicHeader.append("{\"version\":"); + licBody.publicHeader.append(publicHeader.version); + licBody.publicHeader.append("\","); + + licBody.publicHeader.append("\"project\":\""); + licBody.publicHeader.append(publicHeader.projectDescription); + licBody.publicHeader.append("\","); + + licBody.publicHeader.append("\"date\":\""); + licBody.publicHeader.append(publicHeader.date); + licBody.publicHeader.append("\","); + + licBody.publicHeader.append("\"note\":\"poznámka\","); + licBody.publicHeader.append("\"licenceType\":\""); + licBody.publicHeader.append(publicHeader.licenceType); + licBody.publicHeader.append("\","); + + licBody.publicHeader.append("\"items\":["); + + lIdentification.licItemsCount = std::distance(xmlDoc->child("licence").child("items").begin(), xmlDoc->child("licence").child("items").end()); + + int nodeIndex = 0; + int itemIndex = 0; + + for (pugi::xml_node licItemNode : xmlDoc->child("licence").child("items")) + { + licBody.publicHeader.append("{"); + nodeIndex = 0; + itemIndex++; + for (pugi::xml_node child : licItemNode.children()) + { + nodeIndex++; + if (nodeIndex == 1) + { + licBody.publicHeader.append("\"name\":\""); + licBody.publicHeader.append(child.child_value()); + licBody.publicHeader.append("\","); + continue; + } + if (nodeIndex == 3) + { + licBody.publicHeader.append("\"dataPointsCount\":\""); + licBody.publicHeader.append(child.child_value()); + licBody.publicHeader.append("\""); + } + } + if (itemIndex != lIdentification.licItemsCount) + { + licBody.publicHeader.append("},"); + } + else + { + licBody.publicHeader.append("}"); + } + } + + licBody.publicHeader.append("]"); + licBody.publicHeader.append("}"); + } + + string Licence3::getVersion(int middleVersion) + { + string result = ""; + result.append(to_string(generatorVersion)); + result.append("."); + result.append(to_string(middleVersion)); + result.append("."); + string tempLicenceCount = "1"; + result.append(tempLicenceCount); + return result; + } + + bool Licence3::processInputConfiguration() + { + const char *dataRootName = "licence"; + + string licType = xmlDoc->child(dataRootName).child("licenceType").child_value(); + if (!licType.empty()) + { + this->lIdentification.licLicenceType = mapping.licMapTypes[licType]; // LicenceType::EOS_EOV; + this->lIdentification.licTypeName = licType; + } + else + { + errorMessage.code = (int)GeneralError::LicenceMismatch; + errorMessage.message = "ERROR MISSING licenceType"; + return false; + } + + this->lIdentification.licenceVersion = atoi(&xmlDoc->child(dataRootName).child("licenceType").attribute("licenceVersion").value()[0]); + this->lIdentification.revision = atoi(&xmlDoc->child(dataRootName).attribute("revision").value()[0]); + this->lIdentification.licenceIndex = atoi(&xmlDoc->child(dataRootName).child("licenceType").attribute("licenceIndex").value()[0]); + this->lIdentification.licElcType = (ELCType)atoi(&xmlDoc->child(dataRootName).attribute("elc").value()[0]); + + this->lIdentification.licCompatibility = atoi(&xmlDoc->child(dataRootName).attribute("compatibility").value()[0]); + + string plcType = xmlDoc->child(dataRootName).child("plcType").child_value(); + if (!plcType.empty()) + { + this->lIdentification.licPlcType = mapping.licMapPlcType[plcType]; + } + + this->projectDescription = &xmlDoc->child(dataRootName).child("project").child_value()[0]; + + licBody.licenceIdentHeader.compatibilityVersion = this->lIdentification.licCompatibility; + licBody.licenceIdentHeader.licenceIndex = this->lIdentification.licenceIndex; + licBody.licenceIdentHeader.licenceType = (BYTE)this->lIdentification.licLicenceType; + licBody.licenceIdentHeader.licenceTypeVersion = this->lIdentification.licenceVersion; + return true; + } + + void Licence3::getLicenceItems() + { + int nodeIndex = 0; + int itemIndex = 0; + + for (pugi::xml_node licItemNode : xmlDoc->child("licence").child("items")) + { + licDataItem item; + + item.protoId = atoi(licItemNode.child("protoId").child_value()); + item.licCount = atoi(licItemNode.child("dataPointsCount").child_value()); + + this->licBody.privateContent.dataItems.push_back(item); + + nodeIndex = 0; + itemIndex++; + for (pugi::xml_node child : licItemNode.children()) + { + nodeIndex++; + if (nodeIndex == 1) + { + licBody.publicHeader.append("\"name\":\""); + licBody.publicHeader.append(child.child_value()); + licBody.publicHeader.append("\","); + continue; + } + if (nodeIndex == 3) + { + licBody.publicHeader.append("\"dataPointsCount\":\""); + licBody.publicHeader.append(child.child_value()); + licBody.publicHeader.append("\""); + } + } + if (itemIndex != lIdentification.licItemsCount) + { + licBody.publicHeader.append("},"); + } + else + { + licBody.publicHeader.append("}"); + } + } + } + + bool Licence3::createLicence() + { + getLicenceItems(); + getHeader(); + + this->licBody.licenceIdentHeader.licItemCount = this->licBody.privateContent.dataItems.size(); + this->licBody.licenceIdentHeader.publicHeaderLength = this->licBody.publicHeader.length(); + + vector publicContent{}; + vector privateContent{}; + vector privateContentEncrypted{}; + + publicContent.push_back(this->licBody.licId.licIdent[0]); + publicContent.push_back(this->licBody.licId.licIdent[1]); + publicContent.push_back(this->licBody.licId.licIdent[2]); + publicContent.push_back(((char)48 + (int)this->lIdentification.licElcType)); + publicContent.push_back(this->licBody.licId.licIdent[4]); + + publicContent.push_back(this->licBody.licenceIdentHeader.licenceType); + publicContent.push_back(this->licBody.licenceIdentHeader.licenceTypeVersion); + publicContent.push_back(this->licBody.licenceIdentHeader.licenceIndex); + publicContent.push_back(this->licBody.licenceIdentHeader.compatibilityVersion); + publicContent.push_back(this->licBody.privateContent.dataItems.size()); + publicContent.push_back(this->licBody.licenceIdentHeader.publicHeaderLength & 0xFF); + publicContent.push_back((this->licBody.licenceIdentHeader.publicHeaderLength >> 8) & 0xFF); + + appendStringToVector(this->licBody.publicHeader, publicContent); + +#ifdef CRCCHECK + cout << "CRC public size: " << publicContent.size() << "\n"; + cout << "CRC gen public: " << calculateCRC16(publicContent) << "\n"; +#endif + + privateContent.push_back(this->licBody.licenceIdentHeader.licenceType); + privateContent.push_back(this->licBody.licenceIdentHeader.licenceTypeVersion); + privateContent.push_back(this->licBody.licenceIdentHeader.licenceIndex); + privateContent.push_back(this->licBody.licenceIdentHeader.compatibilityVersion); + privateContent.push_back(this->licBody.privateContent.dataItems.size()); + privateContent.push_back(this->licBody.licenceIdentHeader.publicHeaderLength & 0xFF); + privateContent.push_back((this->licBody.licenceIdentHeader.publicHeaderLength >> 8) & 0xFF); + + privateContent.push_back(1); + privateContent.push_back(1); + privateContent.push_back(1); + + for (licDataItem dataItem : this->licBody.privateContent.dataItems) + { + privateContent.push_back(dataItem.protoId & 0xFF); + privateContent.push_back((dataItem.protoId >> 8) & 0xFF); + privateContent.push_back((dataItem.protoId >> 16) & 0xFF); + privateContent.push_back((dataItem.protoId >> 24) & 0xFF); + privateContent.push_back(dataItem.licCount & 0xFF); + privateContent.push_back((dataItem.licCount >> 8) & 0xFF); + privateContent.push_back((dataItem.licCount >> 16) & 0xFF); + privateContent.push_back((dataItem.licCount >> 24) & 0xFF); + } + +#ifdef CRCCHECK + cout << "CRC private size: " << privateContent.size() << "\n"; + cout << "CRC gen private: " << calculateCRC16(privateContent) << "\n"; +#endif + + vector completeVector = joinVectors(publicContent, privateContent); + uint16_t crcComplete = calculateCRC16(completeVector); + +#ifdef CRCCHECK + cout << "CRC complete size: " << completeVector.size() << "\n"; + cout << "CRC gen complete: " << crcComplete << "\n"; +#endif + + privateContent.push_back(crcComplete & 0xFF); + privateContent.push_back((crcComplete >> 8) & 0xFF); + + // cout << "crc complete: " << crcComplete << "\n"; + + // cout << "privateContent length: " << privateContent.size() << "\n"; + // for (auto x : privateContent) cout << (int)x << "-"; + // cout << "\n"; + + privateContentEncrypted = cryptPrivateContent(privateContent); + + // cout << "privateContentEncrypted length: " << privateContentEncrypted.size() << "\n"; + // for (auto x : privateContentEncrypted) cout << (int)x << "-"; + // cout << "\n"; + + string licfileName = getLicenceName(); + std::ofstream outputFile(licfileName, std::ios::out | std::ios::binary); + + // Check if the file is open + if (!outputFile.is_open()) + { + throw LicenceException((int)GeneralError::FileOpenError, "Chyba při zakládání souboru licence: " + uid_path); + } + + std::copy(publicContent.cbegin(), publicContent.cend(), std::ostream_iterator(outputFile)); + std::copy(privateContentEncrypted.cbegin(), privateContentEncrypted.cend(), std::ostream_iterator(outputFile)); + + outputFile.close(); + + cout << licfileName; + return true; + } } - - diff --git a/src/reader/LicenceReader.cpp b/src/reader/LicenceReader.cpp index 59eda7d..8b1465c 100644 --- a/src/reader/LicenceReader.cpp +++ b/src/reader/LicenceReader.cpp @@ -110,6 +110,11 @@ bool LicenceReader::initread(int elcType, InitStructure &initStructure) } case ELCType::ELC3: { + Reader::Licence3 licenceELC3 = Reader::Licence3(this->licIdentification); + this->licence3 = &licenceELC3; + licenceELC3.licenceFilePath = initStructure.licenceFilePath; + this->licence3->readLicence(&this->licencesInfo); + this->licInfo.licenceFileName = this->licence3->licFileName; break; } default: @@ -188,6 +193,32 @@ bool LicenceReader::getLicenceItemInfo(int protocolId, void *returnItemStructure } case ELCType::ELC3: { + if (!this->licIdentification.licCompatibility) // defaultní kompatibilita + { + LicenceELC3Item *resultPtr = static_cast(returnItemStructure); + resultPtr->protocolId = protocolId; + if (this->licencesInfo.licences.count(protocolId)) + resultPtr->dataPointsCount = this->licencesInfo.licences.at(protocolId); + else + { + resultPtr->dataPointsCount = 0; + error.code = 0; + error.message = "Protokol: " + to_string(protocolId) + " nemá licenční body"; + return false; + } + } + else + { + switch (this->licIdentification.licCompatibility) + { + case 1: + // kod pro kompatibilitu 1 + break; + default: + LicenceException((int)GeneralError::CompatibilityTypeNotImplemented, "Kompatibilita není implementována."); + break; + } + } break; } default: diff --git a/src/reader/licReaderELC3.cpp b/src/reader/licReaderELC3.cpp index 5411c1f..dd531d6 100644 --- a/src/reader/licReaderELC3.cpp +++ b/src/reader/licReaderELC3.cpp @@ -1,11 +1,218 @@ #ifndef EZ_APPLICATION_LICENCE_DISABLE #include "licReaderELC3.h" +// #define SHOW 1 namespace Reader { -} + Licence3::Licence3() {} + + Licence3::~Licence3() {} + + Licence3::Licence3(LicenceIdentification &licIdentification) : LicenceELC3(licIdentification) + { + } + + /// @brief načte seznam licenčních bodů do obecné struktury + /// @param licences + /// @return + bool Licence3::readLicence(LicenceInfoGeneral *licences) + { + + //uid load + if (getUID() == false) throw LicenceException((int)GeneralError::UIDReadError, "Nepodařilo se načíst UID: " + uid_path); + + string licFileName = getLicenceName(); + string licFilePath = this->licenceFilePath + licFileName; + + this->licFileName = licFileName; + this->licenceFilePath = licFilePath; + + vector content{}; + if (readFile(licFilePath, content) == false) + { + throw LicenceException((int)GeneralError::FileOpenError, "Chyba otevření souboru licence: " + licFilePath); + } + + + +#ifdef SHOW + cout << "Celý vstup zašifrovaný: \n"; + for (const auto &x : content) + cout << (int)x << "-"; + cout << "\n"; #endif + this->licBody.licId.licIdent[0] = content[0]; + this->licBody.licId.licIdent[1] = content[1]; + this->licBody.licId.licIdent[2] = content[2]; + this->licBody.licId.licIdent[3] = content[3]; + this->licBody.licId.licIdent[4] = content[4]; + this->licBody.licenceIdentHeader.licenceType = content[5]; + this->licBody.licenceIdentHeader.licenceTypeVersion = content[6]; + this->licBody.licenceIdentHeader.licenceIndex = content[7]; + this->licBody.licenceIdentHeader.compatibilityVersion = content[8]; + this->licBody.licenceIdentHeader.licItemCount = content[9]; + this->licBody.licenceIdentHeader.publicHeaderLength = bytesToWord(content[10], content[11]); + + int elcVersion = (int)licBody.licId.licIdent[3] - 48; // verze je text, musí se odečíst 48 + + if (elcVersion != (int)this->lIdentification.licElcType) + { + throw LicenceException((int)GeneralError::ELCMismatch, "Nesouhlasí ELC."); + } + + vector publicPart(content.begin(), content.begin() + 12 + this->licBody.licenceIdentHeader.publicHeaderLength); + + +#ifdef CRCCHECK + cout << "CRC read public size: " << publicPart.size() << "\n"; + cout << "CRC read public: " << calculateCRC16(publicPart) << "\n"; +#endif + +#ifdef SHOW + cout << "\n public header length: " << licBody.licenceIdentHeader.publicHeaderLength << "\n"; +#endif + + vector encryptedPart{}; + + for (unsigned int i = licBody.licenceIdentHeader.publicHeaderLength + 12; i privateContentDecrypted{}; + privateContentDecrypted = decryptPrivateContent(encryptedPart); + + + +#ifdef SHOW + cout << "private encryptedsize: " << encryptedPart.size() << "\n"; + cout << "private decryptedsize: " << privateContentDecrypted.size() << "\n"; + cout << "private decrypted: \n"; + for (const auto &x : privateContentDecrypted) + cout << (int)x << "-"; + cout << "\n"; +#endif + +#ifdef CRCCHECK + cout << "CRC read private size: " << privateContentDecrypted.size() << "\n"; + cout << "CRC read private: " << calculateCRC16(privateContentDecrypted) << "\n"; +#endif + + LicenceBody licBodyDecrypted; + licBodyDecrypted.licenceIdentHeader.licenceType = privateContentDecrypted[0]; + licBodyDecrypted.licenceIdentHeader.licenceTypeVersion = privateContentDecrypted[1]; + licBodyDecrypted.licenceIdentHeader.licenceIndex = privateContentDecrypted[2]; + licBodyDecrypted.licenceIdentHeader.compatibilityVersion = privateContentDecrypted[3]; + licBodyDecrypted.licenceIdentHeader.licItemCount = privateContentDecrypted[4]; + licBodyDecrypted.licenceIdentHeader.publicHeaderLength = bytesToWord(privateContentDecrypted[5], privateContentDecrypted[6]); + + if (licBodyDecrypted.licenceIdentHeader.licItemCount != this->licBody.licenceIdentHeader.licItemCount) + { + throw LicenceException((int)GeneralError::ItemsCountMismatch, "Nesouhlasí počet položek licence."); + } + +#ifdef SHOW + cout << "velikost: " << sizeof(licBodyDecrypted.licenceIdentHeader) << "\n"; +#endif + + int index = 10; + for (int i = 0; i < this->licBody.licenceIdentHeader.licItemCount; i++) + { + licDataItem item{}; + item.protoId = bytesToDword(privateContentDecrypted[index], privateContentDecrypted[index + 1], privateContentDecrypted[index + 2], privateContentDecrypted[index + 3]); + item.licCount = bytesToDword(privateContentDecrypted[index + 4], privateContentDecrypted[index + 5], privateContentDecrypted[index + 7], privateContentDecrypted[index + 7]); + index += sizeof(licDataItem); + this->licBody.privateContent.dataItems.push_back(item); + this->licenceInfo.licences.insert(pair(item.protoId, item.licCount)); + licences->licences.insert(pair(item.protoId, item.licCount)); + } + + uint16_t crcComplete = bytesToWord(privateContentDecrypted[index], privateContentDecrypted[index + 1]); + vector completeVector = joinVectors(publicPart, privateContentDecrypted); + + uint16_t crcCalculated = calculateCRC16(completeVector, 2); + +#ifdef SHOW + // cout << "content: \n"; + // for (const auto x : content) cout << (int)x << "-"; + + cout << "\nvector: \n"; + for (const auto x : completeVector) + cout << (int)x << "-"; + cout << "\n"; + cout << "crcComplete: " << crcComplete << "\n"; + cout << "crcCalculated: " << crcCalculated << "\n"; + cout << "vectorsize: " << completeVector.size() << "\n"; + cout << "public vector size: " << publicPart.size() << "\n"; + cout << "private vector size: " << privateContentDecrypted.size() << "\n"; + for (const auto &pair : this->licenceInfo.licences) + { + cout << "--<" << pair.first << ", " << pair.second << ">--" << endl; + } +#endif + + if (crcCalculated != crcComplete) throw LicenceException((int)GeneralError::LicenceCRCMismatch, "Nesouhlasí CRC."); + + return true; + } + + bool Licence3::getLicenceInfo(void *returnStructure) + { + if (returnStructure != nullptr) + { + LicenceELC2Info *resultPtr = static_cast(returnStructure); + for (auto item : this->licBody.privateContent.dataItems) + { + resultPtr->licences.insert(pair(item.protoId, item.licCount)); + } + } + else + { + errorMessage.code = 1; + errorMessage.message = "Error: Null pointer!"; + return false; + } + + return true; + } + + bool Licence3::getUID() + { + vector content; + if (readFile(this->uid_path + "machine-id", content) == false) + { + return false; + } + + this->uid = string(content.begin(), content.end()); + + return true; + } + +} + +/* +vector content; + if (readFile(this->filePath + "cid", content) == false) + { + return false; + } + + if (content.size() >= CID_LENGTH) + { + for (int i = 0; i < 32; i++) + this->cid[i] = content[i]; + } + else + return false; + + return true; +*/ + +#endif