48#include <QRegularExpression>
50#include "keygenWidget.hh"
55KeyGen::KeyGen(QString n, QString cHash, QString pHash, QString cpHash, QString prHash, QStringList mHashes, QString request) :
66QString KeyGen::computeSignature(
const bool _utf8 )
const {
69 ADD_SALT_PRE(saltPre);
71 ADD_SALT_POST(saltPost);
73 QString keyRequest = saltPre + name + coreHash + pluginHash + cpuHash
74 + productHash + macHashes.join(
"") + saltPost;
76 QString requestSigCheck;
80 QCryptographicHash::hash(keyRequest.toUtf8(),
81 QCryptographicHash::Sha1).toHex();
84 QCryptographicHash::hash(keyRequest.toLatin1(),
85 QCryptographicHash::Sha1).toHex();
87 return requestSigCheck;
90KeyGen::ValidationResult KeyGen::isValid()
const
92 if (requestSig == computeSignature(
true))
96 else if(requestSig == computeSignature(
false))
103QString KeyGen::Generate(QString expiryDate)
const
107 ADD_SALT_PRE(saltPre);
109 ADD_SALT_POST(saltPost);
111 KeyGen::ValidationResult valid = isValid();
117 QString license_ =
"";
120 license_ += expiryDate +
"\n";
121 license_ += name +
"\n";
122 license_ += coreHash +
"\n";
123 license_ += pluginHash +
"\n";
124 license_ += cpuHash +
"\n";
125 license_ += productHash +
"\n";
126 license_ += macHashes.join(
"\n") +
"\n";
128 QString licenseTmp = saltPre + expiryDate + name + coreHash + pluginHash + cpuHash + productHash + macHashes.join(
"") + saltPost;
131 licenseHash = QCryptographicHash::hash ( licenseTmp.toUtf8() , QCryptographicHash::Sha1 ).toHex();
133 licenseHash = QCryptographicHash::hash ( licenseTmp.toLatin1() , QCryptographicHash::Sha1 ).toHex();
135 license_ = licenseHash +
"\n" + license_;
140QString KeyGen::filterString(QString in) {
141 const QRegularExpression validChar(
"[a-f0-9]");
143 out.reserve(in.size());
144 for (QString::iterator it = in.begin(), it_end = in.end(); it != it_end; ++it) {
145 if (validChar.match(*it).hasMatch())
151std::vector<KeyGen> KeyGen::CreateFromMessyString(QString info)
153 const QString dirt =
"[\\s;>]*";
154 const QRegularExpression rx(
"\\b([\\w-]+)" + dirt +
"((?:(?:[a-f0-9]" + dirt +
"){40}){6,})\\b");
155 const QRegularExpression partRe(
"((?:[a-f0-9]" + dirt +
"){40})");
157 std::vector<KeyGen> R;
158 QRegularExpressionMatch rxMatch;
160 while ((pos = info.indexOf(rx, pos, &rxMatch)) != -1) {
161 QString hashesStr = rxMatch.captured(2);
163 QRegularExpressionMatch partReMatch;
165 while ((hashPos = hashesStr.indexOf(partRe, hashPos, &partReMatch)) != -1) {
166 hashes.append(filterString(partReMatch.captured(1)));
167 hashPos += partReMatch.capturedLength(1);
171 std::copy(hashes.begin() + 4, hashes.end() - 1, std::back_inserter(macList));
173 KeyGen K(rxMatch.captured(1),
179 hashes[hashes.count() - 1]);
181 pos += rxMatch.capturedLength(0);
187KeyGenWidget::KeyGenWidget(QMainWindow *parent)
188 : QMainWindow(parent)
191 connect(generateAllButton,SIGNAL(clicked()),
this,SLOT(slotGenerateAllButton()));
192 connect(generateLocalButton,SIGNAL(clicked()),
this,SLOT(slotGenerateButton()));
193 connect(keyList->selectionModel(),SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(handleSelectionChanged(QItemSelection)));
195 connect(splitButton,SIGNAL(clicked()),
this,SLOT(slotSplit()));
197 connect(requestData,SIGNAL(textChanged()),
this,SLOT(slotAnalyze()));
200 connect(days ,SIGNAL(valueChanged(
int)),
this,SLOT(slotDate()));
201 connect(months,SIGNAL(valueChanged(
int)),
this,SLOT(slotDate()));
202 connect(years ,SIGNAL(valueChanged(
int)),
this,SLOT(slotDate()));
207 connect(mangle_pb, SIGNAL(clicked()),
this, SLOT(slotMangle()));
211 expires->setDate( QDate::currentDate());
213 generateLocalButton->setVisible(
false);
214 generateAllButton->setVisible(
false);
217void KeyGenWidget::slotMangle() {
218 const QString hardwareHash_raw = hardwareHashDump_te->toPlainText();
219 const QString pluginHashes_raw = pluginHashDump_te->toPlainText();
221 const std::vector<KeyGen> hardwareKeygens = KeyGen::CreateFromMessyString(hardwareHash_raw);
222 if (hardwareKeygens.empty()) {
223 QMessageBox::critical(
this, tr(
"Unable to Mangle"), tr(
"No valid request found in hardware textbox."));
226 KeyGen hardwareKeygen = hardwareKeygens.front();
228 std::vector<KeyGen> pluginKeygens = KeyGen::CreateFromMessyString(pluginHashes_raw);
229 if (pluginKeygens.empty()) {
230 QMessageBox::critical(
this, tr(
"Unable to Mangle"), tr(
"No valid request found in plugins textbox."));
234 QString generatedRequest;
235 for (std::vector<KeyGen>::iterator it = pluginKeygens.begin(), it_end = pluginKeygens.end();
236 it != it_end; ++it) {
238 it->copyHardwareHashesFrom(hardwareKeygen);
240 generatedRequest += it->generateRequest();
243 requestData->setPlainText(generatedRequest);
246void KeyGenWidget::slotDate() {
247 QDate today = QDate::currentDate();
248 today = today.addDays(days->value());
249 today = today.addMonths(months->value());
250 today = today.addYears(years->value());
252 expires->setDate(today);
255void KeyGenWidget::slotAnalyze() {
256 QString inputData = requestData->toPlainText();
257 keygens_ = KeyGen::CreateFromMessyString(inputData);
260 for (
const auto& keygen : keygens_) {
261 QListWidgetItem *newItem =
new QListWidgetItem( keyList);
262 newItem->setText(keygen.name);
263 newItem->setHidden(
false);
264 KeyGen::ValidationResult r = keygen.isValid();
266 newItem->setForeground(QColor(255, 0, 0));
267 else if (r == KeyGen::LATIN1)
268 newItem->setForeground(QColor(128, 128, 0));
271 generateLocalButton->setVisible(
false);
272 generateAllButton->setVisible(!keygens_.empty());
275void KeyGenWidget::slotSplit() {
277 QString inputData = requestData->toPlainText();
280 QStringList data = inputData.split(
";",Qt::SkipEmptyParts);
282 QString newText = data.join(
"\n");
284 requestData->setText(newText);
288void KeyGenWidget::handleSelectionChanged(
const QItemSelection& selection){
289 generateLocalButton->setVisible(
false);
290 if(keyList->selectionModel()->selectedIndexes().count())
292 int i = keyList->selectionModel()->selectedIndexes()[0].row();
293 setKeyGen(&keygens_[i]);
294 generateLocalButton->setVisible(
true);
295 generateAllButton->setVisible(
true);
297 KeyGen::ValidationResult valid = keygens_[i].isValid();
298 if (valid == KeyGen::INVALID)
299 lbWarning->setText(
"ERROR: Signature does not match.\nCannot generate key");
300 else if (valid == KeyGen::LATIN1)
301 lbWarning->setText(
"WARNING: Request uses old Ascii format.\nKey will be generated with Ascii encoding.");
303 lbWarning->setText(
"");
307KeyGenWidget::~KeyGenWidget() {
311void KeyGenWidget::toFile(
const KeyGen* gen)
313 QString licenseFileName_ = gen->name;
314 std::cerr <<
"Writing License file to output : " << licenseFileName_.toStdString() << std::endl;
315 QFile outFile(licenseFileName_ +
".lic");
317 if (!outFile.open(QIODevice::WriteOnly|QIODevice::Text)) {
318 QMessageBox::critical(
this,tr(
"Unable to open file"),tr(
"Unable to Open output File"));
322 QTextStream output(&outFile);
323 output << gen->Generate(expires->date().toString(Qt::ISODate));
327void KeyGenWidget::setKeyGen(
const KeyGen* gen) {
328 fileNameBox->setText(gen->name);
329 coreHashBox->setText(gen->coreHash);
330 pluginHashBox->setText(gen->pluginHash);
331 cpuHashBox->setText(gen->cpuHash);
332 productIDBox->setText(gen->productHash);
333 macHashBox->setText(gen->macHashes.join(
"\n"));
334 signatureBox->setText(gen->requestSig);
335 generateLocalButton->setEnabled(gen->isValid());
338void KeyGenWidget::slotGenerateButton() {
339 if(keyList->selectionModel()->selectedIndexes().count())
341 int i = keyList->selectionModel()->selectedIndexes()[0].row();
342 toFile(&keygens_[i]);
346void KeyGenWidget::slotGenerateAllButton() {
347 for(
unsigned int i = 0; i < keygens_.size(); i++)
348 toFile(&keygens_[i]);