#include #include #include #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(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(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(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() {}