GenerateLicense.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #include <ExceptionUser.hpp>
  2. #include <ResourceOwned.hpp>
  3. #include <ResourceTraitsWin32.hpp>
  4. #include <xstring.hpp>
  5. #include <bytearray.hpp>
  6. #include <RSACipher.hpp>
  7. #include "Base64.hpp"
  8. #include "SerialNumberGenerator.hpp"
  9. #include <iostream>
  10. #include <ctime>
  11. #include <rapidjson/document.h>
  12. #include <rapidjson/writer.h>
  13. #include <rapidjson/stringbuffer.h>
  14. #undef NKG_CURRENT_SOURCE_FILE
  15. #undef NKG_CURRENT_SOURCE_LINE
  16. #define NKG_CURRENT_SOURCE_FILE() TEXT(".\\navicat-keygen\\GenerateLicense.cpp")
  17. #define NKG_CURRENT_SOURCE_LINE() __LINE__
  18. namespace std {
  19. #if defined(_UNICODE) || defined(UNICODE)
  20. static auto & xcin = wcin;
  21. static auto& xcout = wcout;
  22. static auto& xcerr = wcerr;
  23. #else
  24. static auto& xcin = cin;
  25. static auto& xcout = cout;
  26. static auto& xcerr = cerr;
  27. #endif
  28. }
  29. namespace nkg {
  30. void GenerateLicenseText(const RSACipher& Cipher, const SerialNumberGenerator& Generator) {
  31. std::xstring username;
  32. std::xstring organization;
  33. std::string utf8username;
  34. std::string utf8organization;
  35. std::xstring b64RequestCode;
  36. std::bytearray RequestCode;
  37. std::string utf8RequestInfo;
  38. std::string utf8ResponseInfo;
  39. std::bytearray ResponseCode;
  40. std::xstring b64ResponseCode;
  41. std::xcout << TEXT("[*] Your name: ");
  42. if (!std::getline(std::xcin, username)) {
  43. throw UserAbortionError(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Abort."));
  44. } else {
  45. utf8username = username.explicit_string(CP_UTF8);
  46. }
  47. std::xcout << TEXT("[*] Your organization: ");
  48. if (!std::getline(std::xcin, organization)) {
  49. throw UserAbortionError(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Abort."));
  50. } else {
  51. utf8organization = organization.explicit_string(CP_UTF8);
  52. }
  53. std::xcout << TEXT("[*] Input request code in Base64: (Input empty line to end)") << std::endl;
  54. while (true) {
  55. std::xstring temp;
  56. if (!std::getline(std::xcin, temp)) {
  57. throw UserAbortionError(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Abort."));
  58. }
  59. if (temp.empty()) {
  60. break;
  61. }
  62. b64RequestCode.append(temp);
  63. }
  64. RequestCode = Base64Decode(b64RequestCode);
  65. utf8RequestInfo.resize((Cipher.Bits() + 7) / 8);
  66. Cipher.Decrypt(RequestCode.data(), RequestCode.size(), utf8RequestInfo.data(), RSA_PKCS1_PADDING);
  67. while (utf8RequestInfo.back() == '\x00') {
  68. utf8RequestInfo.pop_back();
  69. }
  70. std::xcout << TEXT("[*] Request Info:") << std::endl;
  71. std::xcout << std::xstring(std::xstring_extension{}, utf8RequestInfo, CP_UTF8) << std::endl;
  72. std::xcout << std::endl;
  73. rapidjson::Document json;
  74. rapidjson::Value N_Key;
  75. rapidjson::Value N_Value;
  76. rapidjson::Value O_Key;
  77. rapidjson::Value O_Value;
  78. rapidjson::Value T_Key;
  79. rapidjson::Value T_Value;
  80. rapidjson::StringBuffer buffer;
  81. rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  82. //
  83. // Begin to parse
  84. //
  85. json.Parse(utf8RequestInfo.c_str());
  86. //
  87. // Remove "Platform" info
  88. //
  89. json.RemoveMember("P");
  90. //
  91. // Set "Name" info
  92. //
  93. N_Key.SetString("N", 1);
  94. N_Value.SetString(utf8username.c_str(), static_cast<rapidjson::SizeType>(utf8username.length()));
  95. //
  96. // Set "Organization" info
  97. //
  98. O_Key.SetString("O", 1);
  99. O_Value.SetString(utf8organization.c_str(), static_cast<rapidjson::SizeType>(utf8organization.length()));
  100. //
  101. // Set "Time" info
  102. //
  103. T_Key.SetString("T", 1);
  104. T_Value.SetUint(static_cast<unsigned int>(std::time(nullptr)));
  105. //
  106. // Add "Name", "Organization" and "Time"
  107. //
  108. json.AddMember(N_Key, N_Value, json.GetAllocator());
  109. json.AddMember(O_Key, O_Value, json.GetAllocator());
  110. json.AddMember(T_Key, T_Value, json.GetAllocator());
  111. json.Accept(writer);
  112. if (buffer.GetSize() > 240) {
  113. throw Exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Response info is too long."));
  114. }
  115. utf8ResponseInfo.assign(buffer.GetString(), buffer.GetSize());
  116. std::xcout << TEXT("[*] Response Info:") << std::endl;
  117. std::xcout << std::xstring(std::xstring_extension{}, utf8ResponseInfo, CP_UTF8) << std::endl;
  118. std::xcout << std::endl;
  119. ResponseCode.resize((Cipher.Bits() + 7) / 8);
  120. Cipher.Encrypt<RSAKeyType::PrivateKey>(utf8ResponseInfo.data(), utf8ResponseInfo.size(), ResponseCode.data(), RSA_PKCS1_PADDING);
  121. b64ResponseCode = Base64Encode(ResponseCode);
  122. std::xcout << TEXT("[*] Activation Code:") << std::endl;
  123. std::xcout << b64ResponseCode << std::endl;
  124. std::xcout << std::endl;
  125. }
  126. void GenerateLicenseBinary(const RSACipher& Cipher, const SerialNumberGenerator& Generator) {
  127. ResourceOwned hLicenseFile(FileHandleTraits{});
  128. std::string utf8SerialNumber = Generator.GetSerialNumberShort().explicit_string(CP_UTF8);
  129. std::xstring username;
  130. std::xstring organization;
  131. std::string utf8username;
  132. std::string utf8organization;
  133. std::string utf8ResponseInfo;
  134. std::bytearray ResponseCode;
  135. std::xcout << TEXT("[*] Your name: ");
  136. if (!std::getline(std::xcin, username)) {
  137. throw UserAbortionError(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Abort."));
  138. } else {
  139. utf8username = username.explicit_string(CP_UTF8);
  140. }
  141. std::xcout << TEXT("[*] Your organization: ");
  142. if (!std::getline(std::xcin, organization)) {
  143. throw UserAbortionError(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Abort."));
  144. } else {
  145. utf8organization = organization.explicit_string(CP_UTF8);
  146. }
  147. rapidjson::Document json;
  148. rapidjson::Value N_Key;
  149. rapidjson::Value N_Value;
  150. rapidjson::Value O_Key;
  151. rapidjson::Value O_Value;
  152. rapidjson::Value T_Key;
  153. rapidjson::Value T_Value;
  154. rapidjson::Value K_Key;
  155. rapidjson::Value K_Value;
  156. rapidjson::StringBuffer buffer;
  157. rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  158. json.Parse("{}");
  159. K_Key.SetString("K", 1);
  160. K_Value.SetString(utf8SerialNumber.c_str(), static_cast<rapidjson::SizeType>(utf8SerialNumber.length()));
  161. N_Key.SetString("N", 1);
  162. N_Value.SetString(utf8username.c_str(), static_cast<rapidjson::SizeType>(utf8username.length()));
  163. O_Key.SetString("O", 1);
  164. O_Value.SetString(utf8organization.c_str(), static_cast<rapidjson::SizeType>(utf8organization.length()));
  165. T_Key.SetString("T", 1);
  166. T_Value.SetUint(static_cast<unsigned int>(std::time(nullptr)));
  167. json.AddMember(K_Key, K_Value, json.GetAllocator());
  168. json.AddMember(N_Key, N_Value, json.GetAllocator());
  169. json.AddMember(O_Key, O_Value, json.GetAllocator());
  170. json.AddMember(T_Key, T_Value, json.GetAllocator());
  171. json.Accept(writer);
  172. if (buffer.GetSize() > 240) {
  173. throw Exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Response info is too long."));
  174. }
  175. utf8ResponseInfo.assign(buffer.GetString(), buffer.GetSize());
  176. std::xcout << TEXT("[*] Response Info:") << std::endl;
  177. std::xcout << std::xstring(std::xstring_extension{}, utf8ResponseInfo, CP_UTF8) << std::endl;
  178. std::xcout << std::endl;
  179. ResponseCode.resize((Cipher.Bits() + 7) / 8);
  180. Cipher.Encrypt<RSAKeyType::PrivateKey>(utf8ResponseInfo.data(), utf8ResponseInfo.size(), ResponseCode.data(), RSA_PKCS1_PADDING);
  181. hLicenseFile.TakeOver(
  182. CreateFile(
  183. TEXT("license_file"),
  184. GENERIC_WRITE,
  185. 0,
  186. NULL,
  187. CREATE_ALWAYS,
  188. FILE_ATTRIBUTE_NORMAL,
  189. NULL
  190. )
  191. );
  192. if (hLicenseFile.IsValid() == false) {
  193. throw Win32Error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), TEXT("CreateFile failed."));
  194. }
  195. DWORD NumberOfBytesWritten;
  196. if (!WriteFile(hLicenseFile, ResponseCode.data(), static_cast<DWORD>(ResponseCode.size()), &NumberOfBytesWritten, NULL)) {
  197. throw Win32Error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), TEXT("WriteFile failed."));
  198. }
  199. std::xcout << TEXT("[+] license_file has been generated.") << std::endl;
  200. }
  201. }