Adjust keygen and add advanced mode
This commit is contained in:
parent
b3cfffddf6
commit
b6aa89bb57
135
navicat-keygen/Helper.cpp
Normal file
135
navicat-keygen/Helper.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
namespace Helper {
|
||||
|
||||
bool ConvertToUTF8(LPCSTR from, std::string& to) {
|
||||
bool bSuccess = false;
|
||||
int len = 0;
|
||||
LPWSTR lpUnicodeString = nullptr;
|
||||
|
||||
len = MultiByteToWideChar(CP_ACP, NULL, from, -1, NULL, 0);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
lpUnicodeString = reinterpret_cast<LPWSTR>(HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
len * sizeof(WCHAR)));
|
||||
if (lpUnicodeString == nullptr)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
if (!MultiByteToWideChar(CP_ACP, NULL, from, -1, lpUnicodeString, len))
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, NULL, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
to.resize(len);
|
||||
if (!WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, to.data(), len, NULL, NULL))
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
while (to.back() == 0)
|
||||
to.pop_back();
|
||||
|
||||
bSuccess = true;
|
||||
|
||||
ON_ConvertToUTF8_0_ERROR:
|
||||
if (lpUnicodeString)
|
||||
HeapFree(GetProcessHeap(), NULL, lpUnicodeString);
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool ConvertToUTF8(LPCWSTR from, std::string& to) {
|
||||
bool bSuccess = false;
|
||||
int len = 0;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, NULL, from, -1, NULL, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_1_ERROR;
|
||||
|
||||
to.resize(len);
|
||||
if (!WideCharToMultiByte(CP_UTF8, NULL, from, -1, to.data(), len, NULL, NULL))
|
||||
goto ON_ConvertToUTF8_1_ERROR;
|
||||
|
||||
while (to.back() == 0)
|
||||
to.pop_back();
|
||||
|
||||
bSuccess = true;
|
||||
|
||||
ON_ConvertToUTF8_1_ERROR:
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool ConvertToUTF8(std::string& str) {
|
||||
bool bSuccess = false;
|
||||
|
||||
std::string temp;
|
||||
bSuccess = ConvertToUTF8(str.c_str(), temp);
|
||||
if (!bSuccess)
|
||||
return false;
|
||||
|
||||
str = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Base64Encode(const std::vector<uint8_t>& bytes) {
|
||||
std::string Result;
|
||||
DWORD pcchString = 0;
|
||||
|
||||
if (bytes.empty())
|
||||
return Result;
|
||||
|
||||
CryptBinaryToStringA(bytes.data(),
|
||||
bytes.size(),
|
||||
CRYPT_STRING_BASE64,
|
||||
NULL,
|
||||
&pcchString);
|
||||
if (pcchString == 0)
|
||||
return Result;
|
||||
|
||||
Result.resize(pcchString + 1);
|
||||
|
||||
if (!CryptBinaryToStringA(bytes.data(),
|
||||
bytes.size(),
|
||||
CRYPT_STRING_BASE64,
|
||||
Result.data(),
|
||||
&pcchString))
|
||||
Result.clear();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Base64Decode(std::string& str) {
|
||||
std::vector<uint8_t> Result;
|
||||
DWORD pcbBinary = 0;
|
||||
|
||||
if (str.empty())
|
||||
return Result;
|
||||
|
||||
CryptStringToBinaryA(str.c_str(),
|
||||
NULL,
|
||||
CRYPT_STRING_BASE64,
|
||||
NULL,
|
||||
&pcbBinary,
|
||||
NULL,
|
||||
NULL);
|
||||
if (pcbBinary == 0)
|
||||
return Result;
|
||||
|
||||
Result.resize(pcbBinary);
|
||||
|
||||
if (!CryptStringToBinaryA(str.c_str(),
|
||||
NULL,
|
||||
CRYPT_STRING_BASE64,
|
||||
Result.data(),
|
||||
&pcbBinary,
|
||||
NULL,
|
||||
NULL))
|
||||
Result.clear();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
}
|
||||
@ -38,93 +38,6 @@ private:
|
||||
std::uniform_int_distribution<int> rand;
|
||||
uint8_t data[10];
|
||||
|
||||
void SetLanguageSigature(Language _language) {
|
||||
switch (_language) {
|
||||
case Language::English:
|
||||
data[5] = 0xAC; // Must be 0xAC for English version.
|
||||
data[6] = 0x88; // Must be 0x88 for English version.
|
||||
break;
|
||||
case Language::SimplifiedChinese:
|
||||
data[5] = 0xCE; // Must be 0xCE for Simplified Chinese version.
|
||||
data[6] = 0x32; // Must be 0x32 for Simplified Chinese version.
|
||||
break;
|
||||
case Language::TraditionalChinese:
|
||||
data[5] = 0xAA; // Must be 0xAA for Traditional Chinese version.
|
||||
data[6] = 0x99; // Must be 0x99 for Traditional Chinese version.
|
||||
break;
|
||||
case Language::Japanese:
|
||||
data[5] = 0xAD; // Must be 0xAD for Japanese version. Discoverer: @dragonflylee
|
||||
data[6] = 0x82; // Must be 0x82 for Japanese version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Polish:
|
||||
data[5] = 0xBB; // Must be 0xBB for Polish version. Discoverer: @dragonflylee
|
||||
data[6] = 0x55; // Must be 0x55 for Polish version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Spanish:
|
||||
data[5] = 0xAE; // Must be 0xAE for Spanish version. Discoverer: @dragonflylee
|
||||
data[6] = 0x10; // Must be 0x10 for Spanish version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::French:
|
||||
data[5] = 0xFA; // Must be 0xFA for French version. Discoverer: @Deltafox79
|
||||
data[6] = 0x20; // Must be 0x20 for French version. Discoverer: @Deltafox79
|
||||
break;
|
||||
case Language::German:
|
||||
data[5] = 0xB1; // Must be 0xB1 for German version. Discoverer: @dragonflylee
|
||||
data[6] = 0x60; // Must be 0x60 for German version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Korean:
|
||||
data[5] = 0xB5; // Must be 0xB5 for Korean version. Discoverer: @dragonflylee
|
||||
data[6] = 0x60; // Must be 0x60 for Korean version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Russian:
|
||||
data[5] = 0xEE; // Must be 0xB5 for Russian version. Discoverer: @dragonflylee
|
||||
data[6] = 0x16; // Must be 0x60 for Russian version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Portuguese:
|
||||
data[5] = 0xCD; // Must be 0xCD for Portuguese version. Discoverer: @dragonflylee
|
||||
data[6] = 0x49; // Must be 0x49 for Portuguese version. Discoverer: @dragonflylee
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetProductSignature(Product _product) {
|
||||
switch (_product) {
|
||||
case Product::DataModeler:
|
||||
data[7] = 0x47;
|
||||
break;
|
||||
case Product::Premium:
|
||||
data[7] = 0x65;
|
||||
break;
|
||||
case Product::MySQL:
|
||||
data[7] = 0x68;
|
||||
break;
|
||||
case Product::PostgreSQL:
|
||||
data[7] = 0x6C;
|
||||
break;
|
||||
case Product::Oracle:
|
||||
data[7] = 0x70;
|
||||
break;
|
||||
case Product::SQLServer:
|
||||
data[7] = 0x74;
|
||||
break;
|
||||
case Product::SQLite:
|
||||
data[7] = 0x78;
|
||||
break;
|
||||
case Product::MariaDB:
|
||||
data[7] = 0x7C;
|
||||
break;
|
||||
case Product::MongoDB:
|
||||
data[7] = 0x80;
|
||||
break;
|
||||
case Product::ReportViewer:
|
||||
data[7] = 0xb;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoEncrypt() {
|
||||
const_DES_cblock DESKey = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 };
|
||||
DES_key_schedule schedule;
|
||||
@ -145,15 +58,111 @@ public:
|
||||
data[1] = 0x2A;
|
||||
}
|
||||
|
||||
void Generate(uint8_t version, Language language, Product product) {
|
||||
void SetLanguageSigature(Language _language) {
|
||||
switch (_language) {
|
||||
case Language::English:
|
||||
data[5] = 0xAC; // Must be 0xAC for English version.
|
||||
data[6] = 0x88; // Must be 0x88 for English version.
|
||||
break;
|
||||
case Language::SimplifiedChinese:
|
||||
data[5] = 0xCE; // Must be 0xCE for Simplified Chinese version.
|
||||
data[6] = 0x32; // Must be 0x32 for Simplified Chinese version.
|
||||
break;
|
||||
case Language::TraditionalChinese:
|
||||
data[5] = 0xAA; // Must be 0xAA for Traditional Chinese version.
|
||||
data[6] = 0x99; // Must be 0x99 for Traditional Chinese version.
|
||||
break;
|
||||
case Language::Japanese:
|
||||
data[5] = 0xAD; // Must be 0xAD for Japanese version. Discoverer: @dragonflylee
|
||||
data[6] = 0x82; // Must be 0x82 for Japanese version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Polish:
|
||||
data[5] = 0xBB; // Must be 0xBB for Polish version. Discoverer: @dragonflylee
|
||||
data[6] = 0x55; // Must be 0x55 for Polish version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Spanish:
|
||||
data[5] = 0xAE; // Must be 0xAE for Spanish version. Discoverer: @dragonflylee
|
||||
data[6] = 0x10; // Must be 0x10 for Spanish version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::French:
|
||||
data[5] = 0xFA; // Must be 0xFA for French version. Discoverer: @Deltafox79
|
||||
data[6] = 0x20; // Must be 0x20 for French version. Discoverer: @Deltafox79
|
||||
break;
|
||||
case Language::German:
|
||||
data[5] = 0xB1; // Must be 0xB1 for German version. Discoverer: @dragonflylee
|
||||
data[6] = 0x60; // Must be 0x60 for German version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Korean:
|
||||
data[5] = 0xB5; // Must be 0xB5 for Korean version. Discoverer: @dragonflylee
|
||||
data[6] = 0x60; // Must be 0x60 for Korean version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Russian:
|
||||
data[5] = 0xEE; // Must be 0xB5 for Russian version. Discoverer: @dragonflylee
|
||||
data[6] = 0x16; // Must be 0x60 for Russian version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Portuguese:
|
||||
data[5] = 0xCD; // Must be 0xCD for Portuguese version. Discoverer: @dragonflylee
|
||||
data[6] = 0x49; // Must be 0x49 for Portuguese version. Discoverer: @dragonflylee
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetLanguageSigature(uint8_t value0, uint8_t value1) {
|
||||
data[5] = value0;
|
||||
data[6] = value1;
|
||||
}
|
||||
|
||||
void SetProductSignature(Product _product) {
|
||||
switch (_product) {
|
||||
case Product::DataModeler:
|
||||
data[7] = 0x47;
|
||||
break;
|
||||
case Product::Premium:
|
||||
data[7] = 0x65;
|
||||
break;
|
||||
case Product::MySQL:
|
||||
data[7] = 0x68;
|
||||
break;
|
||||
case Product::PostgreSQL:
|
||||
data[7] = 0x6C;
|
||||
break;
|
||||
case Product::Oracle:
|
||||
data[7] = 0x70;
|
||||
break;
|
||||
case Product::SQLServer:
|
||||
data[7] = 0x74;
|
||||
break;
|
||||
case Product::SQLite:
|
||||
data[7] = 0x78;
|
||||
break;
|
||||
case Product::MariaDB:
|
||||
data[7] = 0x7C;
|
||||
break;
|
||||
case Product::MongoDB:
|
||||
data[7] = 0x80;
|
||||
break;
|
||||
case Product::ReportViewer:
|
||||
data[7] = 0xb;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetProductSignature(uint8_t value) {
|
||||
data[7] = value;
|
||||
}
|
||||
|
||||
void SetVersion(uint8_t version) {
|
||||
data[8] = version << 4;
|
||||
}
|
||||
|
||||
void Generate() {
|
||||
data[2] = rand(rand_eng);
|
||||
data[3] = rand(rand_eng);
|
||||
data[4] = rand(rand_eng);
|
||||
SetLanguageSigature(language);
|
||||
SetProductSignature(product);
|
||||
data[8] = version << 4;
|
||||
data[9] = 0x32;
|
||||
|
||||
DoEncrypt();
|
||||
}
|
||||
|
||||
@ -161,7 +170,7 @@ public:
|
||||
std::string Key;
|
||||
const char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
|
||||
Key.resize(16 + 1);
|
||||
Key.resize(16);
|
||||
Key[0] = EncodeTable[data[0] >> 3];
|
||||
Key[1] = EncodeTable[(data[0] & 0x07) << 2 | data[1] >> 6];
|
||||
Key[2] = EncodeTable[data[1] >> 1 & 0x1F];
|
||||
@ -179,20 +188,21 @@ public:
|
||||
Key[13] = EncodeTable[data[8] >> 2 & 0x1F];
|
||||
Key[14] = EncodeTable[data[8] << 3 & 0x1F | data[9] >> 5];
|
||||
Key[15] = EncodeTable[data[9] & 0x1F];
|
||||
Key[16] = 0;
|
||||
|
||||
return Key;
|
||||
}
|
||||
|
||||
std::string GetFormatedKey() const {
|
||||
std::string Key = GetKey();
|
||||
|
||||
auto ptr = Key.begin() + 4;
|
||||
Key.insert(ptr++, '-');
|
||||
|
||||
ptr = Key.insert(ptr, '-');
|
||||
ptr++;
|
||||
ptr += 4;
|
||||
Key.insert(ptr++, '-');
|
||||
ptr = Key.insert(ptr, '-');
|
||||
ptr++;
|
||||
ptr += 4;
|
||||
Key.insert(ptr++, '-');
|
||||
Key.insert(ptr, '-');
|
||||
|
||||
return Key;
|
||||
}
|
||||
|
||||
342
navicat-keygen/Process.cpp
Normal file
342
navicat-keygen/Process.cpp
Normal file
@ -0,0 +1,342 @@
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <windows.h>
|
||||
|
||||
#include "RSACipher.hpp"
|
||||
#include "NavicatKeygen.hpp"
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/writer.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
|
||||
namespace Helper {
|
||||
bool ConvertToUTF8(LPCSTR from, std::string& to);
|
||||
bool ConvertToUTF8(LPCWSTR from, std::string& to);
|
||||
bool ConvertToUTF8(std::string& str);
|
||||
|
||||
std::string Base64Encode(const std::vector<uint8_t>& bytes);
|
||||
std::vector<uint8_t> Base64Decode(std::string& str);
|
||||
|
||||
template<int min_num, int max_num>
|
||||
bool ReadNumber(int& num, const char* msg, const char* err_msg) {
|
||||
int temp;
|
||||
std::string input;
|
||||
while (true) {
|
||||
std::cout << msg;
|
||||
if (!std::getline(std::cin, input))
|
||||
return false;
|
||||
|
||||
try {
|
||||
temp = std::stoi(input, nullptr, 0);
|
||||
if (min_num <= temp && temp <= max_num) {
|
||||
num = temp;
|
||||
return true;
|
||||
} else {
|
||||
throw std::invalid_argument("Invalid number");
|
||||
}
|
||||
} catch (...) {
|
||||
std::cout << err_msg << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MODE_SIMPLE 1
|
||||
#define MODE_ADVANCED 2
|
||||
#define FLAG_BIN 1
|
||||
#define FLAG_TEXT 2
|
||||
void Process(RSACipher* cipher, int mode, int flag) {
|
||||
std::string input;
|
||||
int num;
|
||||
|
||||
NavicatKeygen::Product product;
|
||||
NavicatKeygen::Language language;
|
||||
uint8_t product0;
|
||||
uint8_t language0, language1;
|
||||
uint8_t version;
|
||||
NavicatKeygen keygen;
|
||||
std::string username;
|
||||
std::string organization;
|
||||
|
||||
std::string RequestCode_b64;
|
||||
std::vector<uint8_t> RequestCode;
|
||||
char RequestInfo[256] = {};
|
||||
char ResponseInfo[256] = {};
|
||||
std::vector<uint8_t> ResponseCode;
|
||||
std::string ResponseCode_b64;
|
||||
|
||||
rapidjson::Document json;
|
||||
rapidjson::Value N_Key;
|
||||
rapidjson::Value N_Value;
|
||||
rapidjson::Value O_Key;
|
||||
rapidjson::Value O_Value;
|
||||
rapidjson::Value T_Key;
|
||||
rapidjson::Value T_Value;
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
|
||||
if (mode == MODE_SIMPLE) {
|
||||
std::cout << "Select Navicat product:" << std::endl
|
||||
<< "0. DataModeler" << std::endl
|
||||
<< "1. Premium" << std::endl
|
||||
<< "2. MySQL" << std::endl
|
||||
<< "3. PostgreSQL" << std::endl
|
||||
<< "4. Oracle" << std::endl
|
||||
<< "5. SQLServer" << std::endl
|
||||
<< "6. SQLite" << std::endl
|
||||
<< "7. MariaDB" << std::endl
|
||||
<< "8. MongoDB" << std::endl
|
||||
<< "9. ReportViewer" << std::endl
|
||||
<< std::endl;
|
||||
|
||||
if (!Helper::ReadNumber<0, 9>(num,
|
||||
"(Input index)> ",
|
||||
"Invalid index.")) {
|
||||
return;
|
||||
}
|
||||
product = static_cast<NavicatKeygen::Product>(num);
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Select product language:" << std::endl
|
||||
<< "0. English" << std::endl
|
||||
<< "1. Simplified Chinese" << std::endl
|
||||
<< "2. Traditional Chinese" << std::endl
|
||||
<< "3. Japanese" << std::endl
|
||||
<< "4. Polish" << std::endl
|
||||
<< "5. Spanish" << std::endl
|
||||
<< "6. French" << std::endl
|
||||
<< "7. German" << std::endl
|
||||
<< "8. Korean" << std::endl
|
||||
<< "9. Russian" << std::endl
|
||||
<< "10. Portuguese" << std::endl
|
||||
<< std::endl;
|
||||
|
||||
if (!Helper::ReadNumber<0, 10>(num,
|
||||
"(Input index)> ",
|
||||
"Invalid index.")) {
|
||||
return;
|
||||
}
|
||||
language = static_cast<NavicatKeygen::Language>(num);
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
keygen.SetProductSignature(product);
|
||||
keygen.SetLanguageSigature(language);
|
||||
}
|
||||
|
||||
if (mode == MODE_ADVANCED) {
|
||||
|
||||
if (!Helper::ReadNumber<0, 255>(num,
|
||||
"(Navicat Product ID, 0x00 ~ 0xFF)> ",
|
||||
"Invalid number.")) {
|
||||
return;
|
||||
}
|
||||
product0 = static_cast<uint8_t>(num);
|
||||
|
||||
if (!Helper::ReadNumber<0, 255>(num,
|
||||
"(Navicat Language Signature 0, 0x00 ~ 0xFF)> ",
|
||||
"Invalid number.")) {
|
||||
return;
|
||||
}
|
||||
language0 = static_cast<uint8_t>(num);
|
||||
|
||||
if (!Helper::ReadNumber<0, 255>(num,
|
||||
"(Navicat Language Signature 1, 0x00 ~ 0xFF)> ",
|
||||
"Invalid number.")) {
|
||||
return;
|
||||
}
|
||||
language1 = static_cast<uint8_t>(num);
|
||||
|
||||
keygen.SetProductSignature(product0);
|
||||
keygen.SetLanguageSigature(language0, language1);
|
||||
}
|
||||
|
||||
if (!Helper::ReadNumber<0, 16 - 1>(num,
|
||||
"(Input major version number, range: 0 ~ 15, default: 12)> ",
|
||||
"Invalid number.")) {
|
||||
return;
|
||||
}
|
||||
version = static_cast<uint8_t>(num);
|
||||
keygen.SetVersion(version);
|
||||
|
||||
keygen.Generate();
|
||||
std::cout << std::endl;
|
||||
std::cout << "Serial number:" << std::endl;
|
||||
std::cout << keygen.GetFormatedKey() << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Your name: ";
|
||||
if (!std::getline(std::cin, username))
|
||||
return;
|
||||
if (!Helper::ConvertToUTF8(username)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: ConvertToUTF8 fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Your organization: ";
|
||||
if (!std::getline(std::cin, organization))
|
||||
return;
|
||||
if (!Helper::ConvertToUTF8(organization)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: ConvertToUTF8 fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
if (flag == FLAG_TEXT) {
|
||||
std::cout << "Input request code (in Base64), input empty line to end:" << std::endl;
|
||||
while (true) {
|
||||
std::string temp;
|
||||
if (!std::getline(std::cin, temp))
|
||||
return;
|
||||
|
||||
if (temp.empty())
|
||||
break;
|
||||
|
||||
RequestCode_b64 += temp;
|
||||
}
|
||||
|
||||
RequestCode = Helper::Base64Decode(RequestCode_b64);
|
||||
if (RequestCode.empty()) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: Base64Decode fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cipher->Decrypt(RequestCode.data(),
|
||||
RequestCode.size(),
|
||||
RequestInfo,
|
||||
RSA_PKCS1_PADDING)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: Decrypt<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Request Info:" << std::endl;
|
||||
std::cout << RequestInfo << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
json.Parse(RequestInfo);
|
||||
json.RemoveMember("P"); // remove Platform info
|
||||
|
||||
|
||||
N_Key.SetString("N", 1);
|
||||
N_Value.SetString(username.c_str(), username.length());
|
||||
O_Key.SetString("O", 1);
|
||||
O_Value.SetString(organization.c_str(), organization.length());
|
||||
T_Key.SetString("T", 1);
|
||||
T_Value.SetUint(std::time(nullptr));
|
||||
|
||||
json.AddMember(N_Key, N_Value, json.GetAllocator());
|
||||
json.AddMember(O_Key, O_Value, json.GetAllocator());
|
||||
json.AddMember(T_Key, T_Value, json.GetAllocator());
|
||||
|
||||
json.Accept(writer);
|
||||
if (buffer.GetSize() > 240) {
|
||||
std::cout << "ERROR: Response info is too long." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(ResponseInfo, buffer.GetString(), buffer.GetSize());
|
||||
|
||||
std::cout << "Response Info:" << std::endl;
|
||||
std::cout << ResponseInfo << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
ResponseCode.resize(256);
|
||||
|
||||
if (!cipher->Encrypt<RSACipher::KeyType::PrivateKey>(ResponseInfo,
|
||||
strlen(ResponseInfo),
|
||||
ResponseCode.data(),
|
||||
RSA_PKCS1_PADDING)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: Encrypt<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ResponseCode_b64 = Helper::Base64Encode(ResponseCode);
|
||||
if (ResponseCode_b64.empty()) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Base64Encode fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "License:" << std::endl;
|
||||
std::cout << ResponseCode_b64 << std::endl;
|
||||
}
|
||||
|
||||
if (flag == FLAG_BIN) {
|
||||
rapidjson::Value K_Key;
|
||||
rapidjson::Value K_Value;
|
||||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||
DWORD NumberOfBytesWritten;
|
||||
|
||||
json.Parse("{}");
|
||||
|
||||
K_Key.SetString("K", 1);
|
||||
K_Value.SetString(keygen.GetKey().c_str(), keygen.GetKey().size());
|
||||
N_Key.SetString("N", 1);
|
||||
N_Value.SetString(username.c_str(), username.length());
|
||||
O_Key.SetString("O", 1);
|
||||
O_Value.SetString(organization.c_str(), organization.length());
|
||||
T_Key.SetString("T", 1);
|
||||
T_Value.SetUint(std::time(nullptr));
|
||||
|
||||
json.AddMember(K_Key, K_Value, json.GetAllocator());
|
||||
json.AddMember(N_Key, N_Value, json.GetAllocator());
|
||||
json.AddMember(O_Key, O_Value, json.GetAllocator());
|
||||
json.AddMember(T_Key, T_Value, json.GetAllocator());
|
||||
|
||||
json.Accept(writer);
|
||||
if (buffer.GetSize() > 240) {
|
||||
std::cout << "ERROR: Response info is too long." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(ResponseInfo, buffer.GetString(), buffer.GetSize());
|
||||
|
||||
std::cout << "Response Info:" << std::endl;
|
||||
std::cout << ResponseInfo << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
ResponseCode.resize(256);
|
||||
|
||||
if (!cipher->Encrypt<RSACipher::KeyType::PrivateKey>(ResponseInfo,
|
||||
strlen(ResponseInfo),
|
||||
ResponseCode.data(),
|
||||
RSA_PKCS1_PADDING)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: Encrypt<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
hFile = CreateFile(TEXT("license_file"),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
nullptr,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
DWORD dwLastError = GetLastError();
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: CreateFile fails. CODE: " << dwLastError << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WriteFile(hFile, ResponseCode.data(), ResponseCode.size(), &NumberOfBytesWritten, nullptr)) {
|
||||
DWORD dwLastError = GetLastError();
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: WriteFile fails. CODE: " << dwLastError << std::endl;
|
||||
CloseHandle(hFile);
|
||||
return;
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
|
||||
std::cout << "license_file has been generated." << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,460 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
|
||||
#include <tchar.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "NavicatKeygen.hpp"
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/writer.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
|
||||
bool ConvertToUTF8(LPCSTR from, std::string& to) {
|
||||
bool bSuccess = false;
|
||||
int len = 0;
|
||||
LPWSTR lpUnicodeString = nullptr;
|
||||
|
||||
len = MultiByteToWideChar(CP_ACP, NULL, from, -1, NULL, 0);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
lpUnicodeString = reinterpret_cast<LPWSTR>(HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
len * sizeof(WCHAR)));
|
||||
if (lpUnicodeString == nullptr)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
if (!MultiByteToWideChar(CP_ACP, NULL, from, -1, lpUnicodeString, len))
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, NULL, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
to.resize(len);
|
||||
if (!WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, to.data(), len, NULL, NULL))
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
while (to.back() == 0)
|
||||
to.pop_back();
|
||||
|
||||
bSuccess = true;
|
||||
|
||||
ON_ConvertToUTF8_0_ERROR:
|
||||
if (lpUnicodeString)
|
||||
HeapFree(GetProcessHeap(), NULL, lpUnicodeString);
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool ConvertToUTF8(LPCWSTR from, std::string& to) {
|
||||
bool bSuccess = false;
|
||||
int len = 0;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, NULL, from, -1, NULL, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_1_ERROR;
|
||||
|
||||
to.resize(len);
|
||||
if (!WideCharToMultiByte(CP_UTF8, NULL, from, -1, to.data(), len, NULL, NULL))
|
||||
goto ON_ConvertToUTF8_1_ERROR;
|
||||
|
||||
while (to.back() == 0)
|
||||
to.pop_back();
|
||||
|
||||
bSuccess = true;
|
||||
|
||||
ON_ConvertToUTF8_1_ERROR:
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool ConvertToUTF8(std::string& str) {
|
||||
bool bSuccess = false;
|
||||
|
||||
std::string temp;
|
||||
bSuccess = ConvertToUTF8(str.c_str(), temp);
|
||||
if (!bSuccess)
|
||||
return false;
|
||||
|
||||
str = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Base64Encode(const std::vector<uint8_t>& bytes) {
|
||||
std::string Result;
|
||||
DWORD pcchString = 0;
|
||||
|
||||
if (bytes.empty())
|
||||
return Result;
|
||||
|
||||
CryptBinaryToStringA(bytes.data(),
|
||||
bytes.size(),
|
||||
CRYPT_STRING_BASE64,
|
||||
NULL,
|
||||
&pcchString);
|
||||
if (pcchString == 0)
|
||||
return Result;
|
||||
|
||||
Result.resize(pcchString + 1);
|
||||
|
||||
if (!CryptBinaryToStringA(bytes.data(),
|
||||
bytes.size(),
|
||||
CRYPT_STRING_BASE64,
|
||||
Result.data(),
|
||||
&pcchString))
|
||||
Result.clear();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Base64Decode(std::string& str) {
|
||||
std::vector<uint8_t> Result;
|
||||
DWORD pcbBinary = 0;
|
||||
|
||||
if (str.empty())
|
||||
return Result;
|
||||
|
||||
CryptStringToBinaryA(str.c_str(),
|
||||
NULL,
|
||||
CRYPT_STRING_BASE64,
|
||||
NULL,
|
||||
&pcbBinary,
|
||||
NULL,
|
||||
NULL);
|
||||
if (pcbBinary == 0)
|
||||
return Result;
|
||||
|
||||
Result.resize(pcbBinary);
|
||||
|
||||
if (!CryptStringToBinaryA(str.c_str(),
|
||||
NULL,
|
||||
CRYPT_STRING_BASE64,
|
||||
Result.data(),
|
||||
&pcbBinary,
|
||||
NULL,
|
||||
NULL))
|
||||
Result.clear();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
void help() {
|
||||
std::cout << "Usage:" << std::endl;
|
||||
std::cout << " navicat-keygen.exe <RSA-2048 PrivateKey(PEM file)>" << std::endl;
|
||||
}
|
||||
|
||||
bool GatherInformation(NavicatKeygen::Product& product,
|
||||
NavicatKeygen::Language& language,
|
||||
uint8_t& version) {
|
||||
int index = -1;
|
||||
std::string temp;
|
||||
|
||||
std::cout << "Select Navicat product:" << std::endl
|
||||
<< "0. DataModeler" << std::endl
|
||||
<< "1. Premium" << std::endl
|
||||
<< "2. MySQL" << std::endl
|
||||
<< "3. PostgreSQL" << std::endl
|
||||
<< "4. Oracle" << std::endl
|
||||
<< "5. SQLServer" << std::endl
|
||||
<< "6. SQLite" << std::endl
|
||||
<< "7. MariaDB" << std::endl
|
||||
<< "8. MongoDB" << std::endl
|
||||
<< "9. ReportViewer" << std::endl
|
||||
<< std::endl;
|
||||
|
||||
while (true) {
|
||||
std::cout << "(input index)> ";
|
||||
if (!std::getline(std::cin, temp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
index = std::stoi(temp);
|
||||
switch (index) {
|
||||
case 0:
|
||||
product = NavicatKeygen::Product::DataModeler;
|
||||
break;
|
||||
case 1:
|
||||
product = NavicatKeygen::Product::Premium;
|
||||
break;
|
||||
case 2:
|
||||
product = NavicatKeygen::Product::MySQL;
|
||||
break;
|
||||
case 3:
|
||||
product = NavicatKeygen::Product::PostgreSQL;
|
||||
break;
|
||||
case 4:
|
||||
product = NavicatKeygen::Product::Oracle;
|
||||
break;
|
||||
case 5:
|
||||
product = NavicatKeygen::Product::SQLServer;
|
||||
break;
|
||||
case 6:
|
||||
product = NavicatKeygen::Product::SQLite;
|
||||
break;
|
||||
case 7:
|
||||
product = NavicatKeygen::Product::MariaDB;
|
||||
break;
|
||||
case 8:
|
||||
product = NavicatKeygen::Product::MongoDB;
|
||||
break;
|
||||
case 9:
|
||||
product = NavicatKeygen::Product::ReportViewer;
|
||||
break;
|
||||
default:
|
||||
throw std::invalid_argument("Invalid index");
|
||||
}
|
||||
break;
|
||||
} catch (...) {
|
||||
std::cout << "Invalid index." << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Select product language:" << std::endl
|
||||
<< "0. English" << std::endl
|
||||
<< "1. Simplified Chinese" << std::endl
|
||||
<< "2. Traditional Chinese" << std::endl
|
||||
<< "3. Japanese" << std::endl
|
||||
<< "4. Polish" << std::endl
|
||||
<< "5. Spanish" << std::endl
|
||||
<< "6. French" << std::endl
|
||||
<< "7. German" << std::endl
|
||||
<< "8. Korean" << std::endl
|
||||
<< "9. Russian" << std::endl
|
||||
<< "10. Portuguese" << std::endl
|
||||
<< std::endl;
|
||||
|
||||
while (true) {
|
||||
std::cout << "(input index)> ";
|
||||
if (!std::getline(std::cin, temp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
index = std::stoi(temp);
|
||||
switch (index) {
|
||||
case 0:
|
||||
language = NavicatKeygen::Language::English;
|
||||
break;
|
||||
case 1:
|
||||
language = NavicatKeygen::Language::SimplifiedChinese;
|
||||
break;
|
||||
case 2:
|
||||
language = NavicatKeygen::Language::TraditionalChinese;
|
||||
break;
|
||||
case 3:
|
||||
language = NavicatKeygen::Language::Japanese;
|
||||
break;
|
||||
case 4:
|
||||
language = NavicatKeygen::Language::Polish;
|
||||
break;
|
||||
case 5:
|
||||
language = NavicatKeygen::Language::Spanish;
|
||||
break;
|
||||
case 6:
|
||||
language = NavicatKeygen::Language::French;
|
||||
break;
|
||||
case 7:
|
||||
language = NavicatKeygen::Language::German;
|
||||
break;
|
||||
case 8:
|
||||
language = NavicatKeygen::Language::Korean;
|
||||
break;
|
||||
case 9:
|
||||
language = NavicatKeygen::Language::Russian;
|
||||
break;
|
||||
case 10:
|
||||
language = NavicatKeygen::Language::Portuguese;
|
||||
break;
|
||||
default:
|
||||
throw std::invalid_argument("Invalid index");
|
||||
}
|
||||
break;
|
||||
} catch (...) {
|
||||
std::cout << "Invalid index." << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
while (true) {
|
||||
std::cout << "(input major version number)> ";
|
||||
if (!std::getline(std::cin, temp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
version = std::stoi(temp);
|
||||
break;
|
||||
} catch (...) {
|
||||
std::cout << "Invalid index." << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
int _tmain(int argc, LPTSTR argv[]) {
|
||||
if (argc != 2) {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string RSAPrivateKeyPath;
|
||||
RSACipher* cipher = nullptr;
|
||||
std::string RequestCode_b64;
|
||||
std::string ResponseCode_b64;
|
||||
std::vector<uint8_t> RequestCode;
|
||||
std::vector<uint8_t> ResponseCode;
|
||||
char RequestInfo[256] = {};
|
||||
char ResponseInfo[256] = {};
|
||||
|
||||
rapidjson::Document json;
|
||||
|
||||
NavicatKeygen keygen;
|
||||
NavicatKeygen::Product product;
|
||||
NavicatKeygen::Language language;
|
||||
uint8_t version = 0;
|
||||
std::string username;
|
||||
std::string organization;
|
||||
|
||||
cipher = RSACipher::Create();
|
||||
if (cipher == nullptr) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Failed to create RSACipher." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (!ConvertToUTF8(argv[1], RSAPrivateKeyPath)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ConvertToUTF8 fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (!cipher->ImportKeyFromFile<RSACipher::KeyType::PrivateKey>(RSAPrivateKeyPath)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ImportKeyFromFile fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
GatherInformation(product, language, version);
|
||||
|
||||
keygen.Generate(version, language, product);
|
||||
std::cout << "Serial number:" << std::endl;
|
||||
std::cout << keygen.GetFormatedKey() << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Your name: ";
|
||||
if (!std::getline(std::cin, username))
|
||||
goto ON_tmain_ERROR;
|
||||
if (!ConvertToUTF8(username)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ConvertToUTF8 fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
std::cout << "Your organization: ";
|
||||
if (!std::getline(std::cin, organization))
|
||||
goto ON_tmain_ERROR;
|
||||
if (!ConvertToUTF8(organization)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ConvertToUTF8 fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
std::cout << "Input request code (in Base64), input empty line to end:" << std::endl;
|
||||
while (true) {
|
||||
std::string temp;
|
||||
if (!std::getline(std::cin, temp))
|
||||
goto ON_tmain_ERROR;
|
||||
|
||||
if (temp.empty())
|
||||
break;
|
||||
|
||||
RequestCode_b64 += temp;
|
||||
}
|
||||
|
||||
RequestCode = Base64Decode(RequestCode_b64);
|
||||
if (RequestCode.empty()) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Base64Decode fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (!cipher->Decrypt(RequestCode.data(),
|
||||
RequestCode.size(),
|
||||
RequestInfo,
|
||||
RSA_PKCS1_PADDING)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Decrypt<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
std::cout << "Request Info:" << std::endl;
|
||||
std::cout << RequestInfo << std::endl << std::endl;
|
||||
|
||||
json.Parse(RequestInfo);
|
||||
json.RemoveMember("P");
|
||||
|
||||
{
|
||||
rapidjson::Value N_Key;
|
||||
rapidjson::Value N_Value;
|
||||
rapidjson::Value O_Key;
|
||||
rapidjson::Value O_Value;
|
||||
rapidjson::Value T_Key;
|
||||
rapidjson::Value T_Value;
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
|
||||
N_Key.SetString("N", 1);
|
||||
N_Value.SetString(username.c_str(), username.length());
|
||||
O_Key.SetString("O", 1);
|
||||
O_Value.SetString(organization.c_str(), organization.length());
|
||||
T_Key.SetString("T", 1);
|
||||
T_Value.SetUint(std::time(nullptr));
|
||||
|
||||
json.AddMember(N_Key, N_Value, json.GetAllocator());
|
||||
json.AddMember(O_Key, O_Value, json.GetAllocator());
|
||||
json.AddMember(T_Key, T_Value, json.GetAllocator());
|
||||
|
||||
json.Accept(writer);
|
||||
if (buffer.GetSize() > 240) {
|
||||
std::cout << "Response info too long." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
memcpy(ResponseInfo, buffer.GetString(), buffer.GetSize());
|
||||
}
|
||||
|
||||
std::cout << "Response Info:" << std::endl;
|
||||
std::cout << ResponseInfo << std::endl << std::endl;
|
||||
|
||||
ResponseCode.resize(256);
|
||||
|
||||
if (!cipher->Encrypt<RSACipher::KeyType::PrivateKey>(ResponseInfo,
|
||||
strlen(ResponseInfo),
|
||||
ResponseCode.data(),
|
||||
RSA_PKCS1_PADDING)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Encrypt<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
ResponseCode_b64 = Base64Encode(ResponseCode);
|
||||
if (ResponseCode_b64.empty()) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Base64Encode fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
std::cout << "License:" << std::endl;
|
||||
std::cout << ResponseCode_b64 << std::endl;
|
||||
|
||||
ON_tmain_ERROR:
|
||||
if (cipher)
|
||||
delete cipher;
|
||||
return 0;
|
||||
}
|
||||
69
navicat-keygen/main.cpp
Normal file
69
navicat-keygen/main.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include <iostream>
|
||||
#include "RSACipher.hpp"
|
||||
|
||||
namespace Helper {
|
||||
bool ConvertToUTF8(std::string& str);
|
||||
}
|
||||
|
||||
#define MODE_SIMPLE 1
|
||||
#define MODE_ADVANCED 2
|
||||
#define FLAG_BIN 1
|
||||
#define FLAG_TEXT 2
|
||||
void Process(RSACipher* cipher, int mode, int flag);
|
||||
|
||||
void help() {
|
||||
std::cout << "Usage:" << std::endl;
|
||||
std::cout << " navicat-keygen.exe <-bin|-text> [-adv] <RSA-2048 PrivateKey(PEM file)>" << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3 && argc != 4) {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string RSAPrivateKeyPath = argv[argc - 1];
|
||||
RSACipher* cipher = nullptr;
|
||||
|
||||
cipher = RSACipher::Create();
|
||||
if (cipher == nullptr) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: Failed to create RSACipher." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (!Helper::ConvertToUTF8(RSAPrivateKeyPath)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: ConvertToUTF8 fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (!cipher->ImportKeyFromFile<RSACipher::KeyType::PrivateKey>(RSAPrivateKeyPath)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: ImportKeyFromFile<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (argc == 3) {
|
||||
if (_stricmp(argv[1], "-bin") == 0)
|
||||
Process(cipher, MODE_SIMPLE, FLAG_BIN);
|
||||
else if (_stricmp(argv[1], "-text") == 0)
|
||||
Process(cipher, MODE_SIMPLE, FLAG_TEXT);
|
||||
else
|
||||
help();
|
||||
}
|
||||
|
||||
if (argc == 4) {
|
||||
if (_stricmp(argv[1], "-bin") == 0)
|
||||
Process(cipher, MODE_ADVANCED, FLAG_BIN);
|
||||
else if (_stricmp(argv[1], "-text") == 0)
|
||||
Process(cipher, MODE_ADVANCED, FLAG_TEXT);
|
||||
else
|
||||
help();
|
||||
}
|
||||
|
||||
ON_tmain_ERROR:
|
||||
if (cipher)
|
||||
delete cipher;
|
||||
return 0;
|
||||
}
|
||||
@ -166,7 +166,9 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="_tmain.cpp" />
|
||||
<ClCompile Include="Helper.cpp" />
|
||||
<ClCompile Include="Process.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="NavicatKeygen.hpp" />
|
||||
|
||||
@ -15,7 +15,13 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="_tmain.cpp">
|
||||
<ClCompile Include="Helper.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Process.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user