328 lines
12 KiB
C++
328 lines
12 KiB
C++
|
|
|
|
#include "licGenELC2.h"
|
|
|
|
namespace Generator
|
|
{
|
|
Licence2::Licence2()
|
|
{
|
|
}
|
|
|
|
Licence2::~Licence2() {}
|
|
|
|
Licence2::Licence2(string cid, string csd, pugi::xml_document *xmlDoc)
|
|
{
|
|
this->cid = cid;
|
|
this->csd = csd;
|
|
|
|
this->xmlDoc = xmlDoc;
|
|
if (processInputConfiguration() == false)
|
|
throw LicenceException((int)GeneralError::LicenceReadError, "Chyba při čtení licence");
|
|
}
|
|
|
|
void Licence2::getHeader()
|
|
{
|
|
PublicHeader publicHeader;
|
|
publicHeader.version = getVersion(lIdentification.revision);
|
|
publicHeader.projectDescription = projectDescription;
|
|
publicHeader.date = "4.4.2024"; //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 Licence2::getVersion(int middleVersion)
|
|
{
|
|
string result = "";
|
|
result.append(to_string(generatorVersion));
|
|
result.append(".");
|
|
result.append(to_string(middleVersion));
|
|
result.append(".");
|
|
string tempLicenceCount = "1"; // TODO
|
|
result.append(tempLicenceCount);
|
|
return result;
|
|
}
|
|
|
|
bool Licence2::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.cardSize={};
|
|
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;
|
|
licBody.licenceIdentHeader.serialNumber={};
|
|
|
|
return true;
|
|
}
|
|
|
|
void Licence2::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 Licence2::createLicence()
|
|
{
|
|
getLicenceItems();
|
|
getHeader();
|
|
|
|
sdCard = SDCard(this->cid, this->csd);
|
|
if (sdCard.isLoaded == false)
|
|
throw LicenceException((int)GeneralError::SDCardReadError, "Chyba při čtení SD karty, cesta: " + cid_cdsPath);
|
|
|
|
this->licBody.licenceIdentHeader.cardSize = sdCard.cardData.cardSize;
|
|
this->licBody.licenceIdentHeader.serialNumber = sdCard.cardData.serialNumber;
|
|
this->licBody.licenceIdentHeader.licItemCount = this->licBody.privateContent.dataItems.size();
|
|
this->licBody.licenceIdentHeader.publicHeaderLength = this->licBody.publicHeader.length();
|
|
|
|
vector<unsigned char> publicContent {};
|
|
vector<unsigned char> privateContent {};
|
|
vector<unsigned char> 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);
|
|
publicContent.push_back(this->licBody.licenceIdentHeader.cardSize & 0xFF);
|
|
publicContent.push_back((this->licBody.licenceIdentHeader.cardSize >> 8) & 0xFF);
|
|
publicContent.push_back(this->licBody.licenceIdentHeader.serialNumber & 0xFF);
|
|
publicContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 8) & 0xFF);
|
|
publicContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 16) & 0xFF);
|
|
publicContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 24) & 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(this->licBody.licenceIdentHeader.cardSize & 0xFF);
|
|
privateContent.push_back((this->licBody.licenceIdentHeader.cardSize >> 8) & 0xFF);
|
|
privateContent.push_back(this->licBody.licenceIdentHeader.serialNumber & 0xFF);
|
|
privateContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 8) & 0xFF);
|
|
privateContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 16) & 0xFF);
|
|
privateContent.push_back((this->licBody.licenceIdentHeader.serialNumber >> 24) & 0xFF);
|
|
|
|
privateContent.push_back(1);
|
|
privateContent.push_back(1);
|
|
privateContent.push_back(1);
|
|
|
|
|
|
|
|
// cout << "basic private: \n";
|
|
// for (const auto x : privateContent) cout << (int)x << "-";
|
|
// cout << "\n";
|
|
|
|
for (licDataItem dataItem : this->licBody.privateContent.dataItems)
|
|
{
|
|
cout << "proto: " << dataItem.protoId << "---";
|
|
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);
|
|
for (const auto x : privateContent) cout << (int)x << "-";
|
|
cout << "\n";
|
|
//for (unsigned int i = 0; i < sizeof(dataItem.dummy); i++) privateContent.push_back(i);
|
|
}
|
|
|
|
cout << "\n final private \n";
|
|
|
|
|
|
#ifdef CRCCHECK
|
|
cout << "CRC private size: " << privateContent.size() << "\n";
|
|
cout << "CRC gen private: " << calculateCRC16(privateContent) << "\n";
|
|
#endif
|
|
|
|
vector<unsigned char> 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: " + cid_cdsPath);
|
|
}
|
|
|
|
std::copy(publicContent.cbegin(), publicContent.cend(), std::ostream_iterator<unsigned char>(outputFile));
|
|
std::copy(privateContentEncrypted.cbegin(), privateContentEncrypted.cend(), std::ostream_iterator<unsigned char>(outputFile));
|
|
|
|
outputFile.close();
|
|
|
|
cout << licfileName;
|
|
return true;
|
|
}
|
|
|
|
}
|