mirror of
https://github.com/Neo-Desktop/WindowsXPKg
synced 2025-12-02 16:25:13 +02:00
Refactor/Overhaul (#40)
* major refactor/overhaul
move generation implementation to libumskt/*
decouple CLI/Options (and JSON) from generation implementation
set groundwork for future shared library
use standardized PIDGEN2/PIDGEN3 naming convention
create a Windows Docker file for quick compilation
add Windows resouce file/header so we have an application icon on windows
use icon from @Endermanch (used with permission)
add support for fully-static linux/muslc-based compilation
add support for a dos/windows (i486+) binary using djgpp
add Dockerfile to compile gcc/djgpp/watt32/openssl to provide DOS (DPMI) binaries
add @Endermanch 's Vista+ documentation
update Readme for recent credits
* begin work on C linkage and emscripten buildpath
* Update CMake to include and build Crypto++
* move dllmain.cpp to the correct directory
* add rust port info to README.md
* re-add dropped changes from rebase
* update build config, specify windows XP version number for crypto++
* update dos-djgpp action to use new cmake builder and options
* update dos-djgpp to use UMSKT hosted forks
* update other workflows to include standard header
* remove crypto++ from build config for now
* use the new `shell` parameter in `threeal/cmake-action`
TODO: move to a stable version (v1.3.0) when ready
* use full commit hash because a shortened hash is unsupported
* add the required {0} parameter?
* add openssl 3.1.1 to windows github runners
* ensure linux matrix build compiles on the correct arch
---------
Co-authored-by: Neo <321592+Neo-Desktop@users.noreply.github.com>
This commit is contained in:
76
src/cli.cpp
76
src/cli.cpp
@@ -21,18 +21,21 @@
|
||||
*/
|
||||
|
||||
#include "cli.h"
|
||||
#include "confid.h"
|
||||
#include "BINK1998.h"
|
||||
#include "BINK2002.h"
|
||||
|
||||
bool CLI::loadJSON(const fs::path& filename, json *output) {
|
||||
if (!fs::exists(filename)) {
|
||||
if (!filename.empty() && !fs::exists(filename)) {
|
||||
fmt::print("ERROR: File {} does not exist\n", filename.string());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ifstream f(filename);
|
||||
*output = json::parse(f, nullptr, false, false);
|
||||
else if (fs::exists(filename)) {
|
||||
std::ifstream f(filename);
|
||||
*output = json::parse(f, nullptr, false, false);
|
||||
}
|
||||
else if (filename.empty()) {
|
||||
cmrc::embedded_filesystem fs = cmrc::umskt::get_filesystem();
|
||||
cmrc::file keys = fs.open("keys.json");
|
||||
*output = json::parse(keys, nullptr, false, false);
|
||||
}
|
||||
|
||||
if (output->is_discarded()) {
|
||||
fmt::print("ERROR: Unable to parse keys from {}\n", filename.string());
|
||||
@@ -48,39 +51,40 @@ void CLI::showHelp(char *argv[]) {
|
||||
fmt::print("\t-h --help\tshow this message\n");
|
||||
fmt::print("\t-v --verbose\tenable verbose output\n");
|
||||
fmt::print("\t-n --number\tnumber of keys to generate (defaults to 1)\n");
|
||||
fmt::print("\t-f --file\tspecify which keys file to load (defaults to keys.json)\n");
|
||||
fmt::print("\t-f --file\tspecify which keys file to load\n");
|
||||
fmt::print("\t-i --instid\tinstallation ID used to generate confirmation ID\n");
|
||||
fmt::print("\t-b --binkid\tspecify which BINK identifier to load (defaults to 2E)\n");
|
||||
fmt::print("\t-l --list\tshow which products/binks can be loaded\n");
|
||||
fmt::print("\t-c --channelid\tspecify which Channel Identifier to use (defaults to 640)\n");
|
||||
fmt::print("\t-s --serial\tspecifies a serial to use in the product ID (defaults to random, BINK1998 only)\n");
|
||||
fmt::print("\t-V --validate\tproduct key to validate signature\n");
|
||||
fmt::print("\n\n");
|
||||
fmt::print("\n");
|
||||
}
|
||||
|
||||
int CLI::parseCommandLine(int argc, char* argv[], Options* options) {
|
||||
// set default options
|
||||
*options = Options {
|
||||
"2E",
|
||||
"keys.json",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
640,
|
||||
false,
|
||||
0,
|
||||
1,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
MODE_BINK1998_GENERATE
|
||||
};
|
||||
// set default options
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
std::string arg = argv[i];
|
||||
|
||||
if (arg == "-v" || arg == "--verbose") {
|
||||
options->verbose = true;
|
||||
UMSKT::setDebugOutput(stderr);
|
||||
} else if (arg == "-h" || arg == "--help") {
|
||||
options->help = true;
|
||||
} else if (arg == "-n" || arg == "--number") {
|
||||
@@ -168,8 +172,20 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) {
|
||||
}
|
||||
|
||||
int CLI::validateCommandLine(Options* options, char *argv[], json *keys) {
|
||||
if (options->help || options->error) {
|
||||
if (options->error) {
|
||||
fmt::print("error parsing command line options\n");
|
||||
}
|
||||
showHelp(argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (options->verbose) {
|
||||
fmt::print("Loading keys file {}\n", options->keysFilename);
|
||||
if(options->keysFilename.empty()) {
|
||||
fmt::print("Loading internal keys file\n");
|
||||
} else {
|
||||
fmt::print("Loading keys file {}\n", options->keysFilename);
|
||||
}
|
||||
}
|
||||
|
||||
if (!loadJSON(options->keysFilename, keys)) {
|
||||
@@ -177,15 +193,11 @@ int CLI::validateCommandLine(Options* options, char *argv[], json *keys) {
|
||||
}
|
||||
|
||||
if (options->verbose) {
|
||||
fmt::print("Loaded keys from {} successfully\n",options->keysFilename);
|
||||
}
|
||||
|
||||
if (options->help || options->error) {
|
||||
if (options->error) {
|
||||
fmt::print("error parsing command line options\n");
|
||||
if(options->keysFilename.empty()) {
|
||||
fmt::print("Loaded internal keys file successfully\n");
|
||||
} else {
|
||||
fmt::print("Loaded keys from {} successfully\n",options->keysFilename);
|
||||
}
|
||||
showHelp(argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (options->list) {
|
||||
@@ -223,8 +235,7 @@ int CLI::validateCommandLine(Options* options, char *argv[], json *keys) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CLI::printID(DWORD *pid)
|
||||
{
|
||||
void CLI::printID(DWORD *pid) {
|
||||
char raw[12];
|
||||
char b[6], c[8];
|
||||
int i, digit = 0;
|
||||
@@ -276,8 +287,8 @@ bool CLI::stripKey(const char *in_key, char out_key[PK_LENGTH]) {
|
||||
if (i >= PK_LENGTH)
|
||||
return false;
|
||||
// convert to uppercase - if character allowed, copy into array
|
||||
for (int j = 0; j < strlen(pKeyCharset); j++) {
|
||||
if (toupper(*p) == pKeyCharset[j]) {
|
||||
for (int j = 0; j < strlen(PIDGEN3::pKeyCharset); j++) {
|
||||
if (toupper(*p) == PIDGEN3::pKeyCharset[j]) {
|
||||
out_key[i++] = toupper(*p);
|
||||
continue;
|
||||
}
|
||||
@@ -321,7 +332,8 @@ CLI::CLI(Options options, json keys) {
|
||||
fmt::print("\n");
|
||||
}
|
||||
|
||||
eCurve = initializeEllipticCurve(
|
||||
|
||||
eCurve = PIDGEN3::initializeEllipticCurve(
|
||||
this->keys["BINK"][this->BINKID]["p"].get<std::string>(),
|
||||
this->keys["BINK"][this->BINKID]["a"].get<std::string>(),
|
||||
this->keys["BINK"][this->BINKID]["b"].get<std::string>(),
|
||||
@@ -371,9 +383,9 @@ int CLI::BINK1998Generate() {
|
||||
bool bUpgrade = false;
|
||||
|
||||
for (int i = 0; i < this->total; i++) {
|
||||
BINK1998::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, nRaw, bUpgrade, this->pKey);
|
||||
PIDGEN3::BINK1998::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, nRaw, bUpgrade, this->pKey);
|
||||
|
||||
bool isValid = BINK1998::Verify(this->eCurve, this->genPoint, this->pubPoint, this->pKey);
|
||||
bool isValid = PIDGEN3::BINK1998::Verify(this->eCurve, this->genPoint, this->pubPoint, this->pKey);
|
||||
if (isValid) {
|
||||
CLI::printKey(this->pKey);
|
||||
if (i < this->total - 1 || this->options.verbose) {
|
||||
@@ -420,11 +432,11 @@ int CLI::BINK2002Generate() {
|
||||
fmt::print("> AuthInfo: {}\n", pAuthInfo);
|
||||
}
|
||||
|
||||
BINK2002::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, pChannelID, pAuthInfo, false, this->pKey);
|
||||
PIDGEN3::BINK2002::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, pChannelID, pAuthInfo, false, this->pKey);
|
||||
CLI::printKey(this->pKey);
|
||||
fmt::print("\n");
|
||||
|
||||
bool isValid = BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, this->pKey);
|
||||
bool isValid = PIDGEN3::BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, this->pKey);
|
||||
if (isValid) {
|
||||
CLI::printKey(this->pKey);
|
||||
if (i < this->total - 1 || this->options.verbose) {
|
||||
@@ -464,7 +476,7 @@ int CLI::BINK1998Validate() {
|
||||
|
||||
CLI::printKey(product_key);
|
||||
fmt::print("\n");
|
||||
if (!BINK1998::Verify(this->eCurve, this->genPoint, this->pubPoint, product_key)) {
|
||||
if (!PIDGEN3::BINK1998::Verify(this->eCurve, this->genPoint, this->pubPoint, product_key)) {
|
||||
fmt::print("ERROR: Product key is invalid! Wrong BINK ID?\n");
|
||||
return 1;
|
||||
}
|
||||
@@ -483,7 +495,7 @@ int CLI::BINK2002Validate() {
|
||||
|
||||
CLI::printKey(product_key);
|
||||
fmt::print("\n");
|
||||
if (!BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, product_key)) {
|
||||
if (!PIDGEN3::BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, product_key)) {
|
||||
fmt::print("ERROR: Product key is invalid! Wrong BINK ID?\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
36
src/cli.h
36
src/cli.h
@@ -25,6 +25,42 @@
|
||||
|
||||
#include "header.h"
|
||||
|
||||
#include <cmrc/cmrc.hpp>
|
||||
|
||||
#include "libumskt/libumskt.h"
|
||||
#include "libumskt/pidgen2/PIDGEN2.h"
|
||||
#include "libumskt/pidgen3/PIDGEN3.h"
|
||||
#include "libumskt/pidgen3/BINK1998.h"
|
||||
#include "libumskt/pidgen3/BINK2002.h"
|
||||
#include "libumskt/confid/confid.h"
|
||||
|
||||
CMRC_DECLARE(umskt);
|
||||
|
||||
enum MODE {
|
||||
MODE_BINK1998_GENERATE = 0,
|
||||
MODE_BINK2002_GENERATE = 1,
|
||||
MODE_CONFIRMATION_ID = 2,
|
||||
MODE_BINK1998_VALIDATE = 3,
|
||||
MODE_BINK2002_VALIDATE = 4,
|
||||
};
|
||||
|
||||
struct Options {
|
||||
std::string binkid;
|
||||
std::string keysFilename;
|
||||
std::string instid;
|
||||
std::string keyToCheck;
|
||||
int channelID;
|
||||
int serial;
|
||||
int numKeys;
|
||||
bool serialSet;
|
||||
bool verbose;
|
||||
bool help;
|
||||
bool error;
|
||||
bool list;
|
||||
|
||||
MODE applicationMode;
|
||||
};
|
||||
|
||||
class CLI {
|
||||
Options options;
|
||||
json keys;
|
||||
|
||||
100
src/header.h
100
src/header.h
@@ -23,18 +23,8 @@
|
||||
#ifndef UMSKT_HEADER_H
|
||||
#define UMSKT_HEADER_H
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <cassert>
|
||||
#else
|
||||
#define assert(x) /* nothing */
|
||||
#endif
|
||||
#include "typedefs.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
@@ -45,95 +35,7 @@
|
||||
#include <fmt/core.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
// Algorithm macros
|
||||
#define PK_LENGTH 25
|
||||
#define NULL_TERMINATOR 1
|
||||
|
||||
#define FIELD_BITS 384
|
||||
#define FIELD_BYTES 48
|
||||
#define FIELD_BITS_2003 512
|
||||
#define FIELD_BYTES_2003 64
|
||||
|
||||
#define SHA_MSG_LENGTH_XP (4 + 2 * FIELD_BYTES)
|
||||
#define SHA_MSG_LENGTH_2003 (3 + 2 * FIELD_BYTES_2003)
|
||||
|
||||
#define NEXTSNBITS(field, n, offset) (((QWORD)(field) >> (offset)) & ((1ULL << (n)) - 1))
|
||||
#define FIRSTNBITS(field, n) NEXTSNBITS((field), (n), 0)
|
||||
|
||||
#define HIBYTES(field, bytes) NEXTSNBITS((QWORD)(field), ((bytes) * 8), ((bytes) * 8))
|
||||
#define LOBYTES(field, bytes) FIRSTNBITS((QWORD)(field), ((bytes) * 8))
|
||||
|
||||
#define BYDWORD(n) (DWORD)(*((n) + 0) | *((n) + 1) << 8 | *((n) + 2) << 16 | *((n) + 3) << 24)
|
||||
#define BITMASK(n) ((1ULL << (n)) - 1)
|
||||
|
||||
using json = nlohmann::json;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
enum MODE {
|
||||
MODE_BINK1998_GENERATE = 0,
|
||||
MODE_BINK2002_GENERATE = 1,
|
||||
MODE_CONFIRMATION_ID = 2,
|
||||
MODE_BINK1998_VALIDATE = 3,
|
||||
MODE_BINK2002_VALIDATE = 4,
|
||||
};
|
||||
|
||||
struct Options {
|
||||
std::string binkid;
|
||||
std::string keysFilename;
|
||||
std::string instid;
|
||||
std::string keyToCheck;
|
||||
int channelID;
|
||||
bool serialSet;
|
||||
int serial;
|
||||
int numKeys;
|
||||
bool verbose;
|
||||
bool help;
|
||||
bool error;
|
||||
bool list;
|
||||
|
||||
MODE applicationMode;
|
||||
};
|
||||
|
||||
// Type definitions
|
||||
typedef bool BOOL;
|
||||
typedef uint8_t BYTE;
|
||||
typedef uint16_t WORD;
|
||||
typedef uint32_t DWORD;
|
||||
typedef uint64_t QWORD;
|
||||
|
||||
#ifdef __SIZEOF_INT128__
|
||||
typedef unsigned __int128 OWORD;
|
||||
#endif
|
||||
|
||||
// Global variables
|
||||
extern Options options;
|
||||
|
||||
// util.cpp
|
||||
int BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen); // Hello OpenSSL developers, please tell me, where is this function at?
|
||||
void endian(BYTE *data, int length);
|
||||
|
||||
EC_GROUP *initializeEllipticCurve(
|
||||
std::string pSel,
|
||||
std::string aSel,
|
||||
std::string bSel,
|
||||
std::string generatorXSel,
|
||||
std::string generatorYSel,
|
||||
std::string publicKeyXSel,
|
||||
std::string publicKeyYSel,
|
||||
EC_POINT *&genPoint,
|
||||
EC_POINT *&pubPoint
|
||||
);
|
||||
|
||||
// key.cpp
|
||||
extern char pKeyCharset[];
|
||||
void unbase24(BYTE *byteSeq, const char *cdKey);
|
||||
void base24(char *cdKey, BYTE *byteSeq);
|
||||
|
||||
|
||||
#endif //UMSKT_HEADER_H
|
||||
|
||||
@@ -62,7 +62,7 @@ inline QWORD ConfirmationID::__umul128(QWORD a, QWORD b, QWORD* hi)
|
||||
#else
|
||||
#define __umul128 _umul128
|
||||
#endif
|
||||
#elif defined(__i386__) || defined(_M_IX86) || defined(__arm__)
|
||||
#elif defined(__i386__) || defined(_M_IX86) || defined(__arm__) || defined(__EMSCRIPTEN__)
|
||||
inline QWORD ConfirmationID::__umul128(QWORD multiplier, QWORD multiplicand, QWORD *product_hi) {
|
||||
// multiplier = ab = a * 2^32 + b
|
||||
// multiplicand = cd = c * 2^32 + d
|
||||
@@ -87,6 +87,8 @@ inline QWORD ConfirmationID::__umul128(QWORD multiplier, QWORD multiplicand, QWO
|
||||
|
||||
return product_lo;
|
||||
}
|
||||
#else
|
||||
#error Unknown architecture detected - please edit confid.cpp to tailor __umul128() your architecture
|
||||
#endif
|
||||
|
||||
QWORD ConfirmationID::ui128_quotient_mod(QWORD lo, QWORD hi)
|
||||
@@ -23,7 +23,7 @@
|
||||
#ifndef UMSKT_CONFID_H
|
||||
#define UMSKT_CONFID_H
|
||||
|
||||
#include "header.h"
|
||||
#include "../libumskt.h"
|
||||
|
||||
// Confirmation ID generator constants
|
||||
#define SUCCESS 0
|
||||
@@ -40,7 +40,7 @@ typedef struct {
|
||||
QWORD v[2];
|
||||
} TDivisor;
|
||||
|
||||
class ConfirmationID {
|
||||
EXPORT class ConfirmationID {
|
||||
static QWORD residue_add(QWORD x, QWORD y);
|
||||
static QWORD residue_sub(QWORD x, QWORD y);
|
||||
static QWORD __umul128(QWORD a, QWORD b, QWORD* hi);
|
||||
@@ -65,7 +65,7 @@ class ConfirmationID {
|
||||
|
||||
public:
|
||||
static int Generate(const char* installation_id_str, char confirmation_id[49]);
|
||||
static int CLIRun();
|
||||
//EXPORT static int CLIRun();
|
||||
};
|
||||
|
||||
#endif //UMSKT_CONFID_H
|
||||
35
src/libumskt/debugoutput.cpp
Normal file
35
src/libumskt/debugoutput.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 6/25/2023
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "libumskt.h"
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
std::FILE* UMSKT::debug = std::fopen("NUL:", "w");
|
||||
#else
|
||||
std::FILE* UMSKT::debug = std::fopen("/dev/null", "w");
|
||||
#endif
|
||||
|
||||
|
||||
void UMSKT::setDebugOutput(std::FILE* input) {
|
||||
debug = input;
|
||||
}
|
||||
60
src/libumskt/libumskt.cpp
Normal file
60
src/libumskt/libumskt.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 6/25/2023
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "libumskt.h"
|
||||
#include "confid/confid.h"
|
||||
#include "pidgen3/PIDGEN3.h"
|
||||
#include "pidgen3/BINK1998.h"
|
||||
#include "pidgen3/BINK2002.h"
|
||||
#include "pidgen2/PIDGEN2.h"
|
||||
|
||||
FNEXPORT int ConfirmationID_Generate(const char* installation_id_str, char confirmation_id[49]) {
|
||||
return ConfirmationID::Generate(installation_id_str, confirmation_id);
|
||||
}
|
||||
|
||||
FNEXPORT EC_GROUP* PIDGEN3_initializeEllipticCurve(char* pSel, char* aSel, char* bSel, char* generatorXSel, char* generatorYSel, char* publicKeyXSel, char* publicKeyYSel, EC_POINT *&genPoint, EC_POINT *&pubPoint) {
|
||||
return PIDGEN3::initializeEllipticCurve(pSel, aSel, bSel, generatorXSel, generatorYSel, publicKeyXSel, publicKeyYSel, genPoint, pubPoint);
|
||||
}
|
||||
|
||||
FNEXPORT bool PIDGEN3_BINK1998_Verify(EC_GROUP *eCurve, EC_POINT *basePoint, EC_POINT *publicKey, char (&pKey)[25]) {
|
||||
return PIDGEN3::BINK1998::Verify(eCurve, basePoint, publicKey, pKey);
|
||||
}
|
||||
|
||||
FNEXPORT void PIDGEN3_BINK1998_Generate(EC_GROUP *eCurve, EC_POINT *basePoint, BIGNUM *genOrder, BIGNUM *privateKey, DWORD pSerial, BOOL pUpgrade,char (&pKey)[25]) {
|
||||
return PIDGEN3::BINK1998::Generate(eCurve, basePoint, genOrder, privateKey, pSerial, pUpgrade, pKey);
|
||||
}
|
||||
|
||||
FNEXPORT bool PIDGEN3_BINK2002_Verify(EC_GROUP *eCurve, EC_POINT *basePoint, EC_POINT *publicKey, char (&cdKey)[25]) {
|
||||
return PIDGEN3::BINK2002::Verify(eCurve, basePoint, publicKey, cdKey);
|
||||
}
|
||||
|
||||
FNEXPORT void PIDGEN3_BINK2002_Generate(EC_GROUP *eCurve, EC_POINT *basePoint, BIGNUM *genOrder, BIGNUM *privateKey, DWORD pChannelID, DWORD pAuthInfo, BOOL pUpgrade, char (&pKey)[25]) {
|
||||
return PIDGEN3::BINK2002::Generate(eCurve, basePoint, genOrder, privateKey, pChannelID, pAuthInfo, pUpgrade, pKey);
|
||||
}
|
||||
|
||||
FNEXPORT int PIDGEN2_GenerateRetail(char* channelID, char* &keyout) {
|
||||
return PIDGEN2::GenerateRetail(channelID, keyout);
|
||||
}
|
||||
|
||||
FNEXPORT int PIDGEN2_GenerateOEM(char* year, char* day, char* oem, char* keyout) {
|
||||
return PIDGEN2::GenerateOEM(year, day, oem, keyout);
|
||||
}
|
||||
73
src/libumskt/libumskt.h
Normal file
73
src/libumskt/libumskt.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 6/24/2023
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#ifndef UMSKT_LIBUMSKT_H
|
||||
#define UMSKT_LIBUMSKT_H
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
// Algorithm macros
|
||||
#define PK_LENGTH 25
|
||||
#define NULL_TERMINATOR 1
|
||||
|
||||
#define FIELD_BITS 384
|
||||
#define FIELD_BYTES 48
|
||||
#define FIELD_BITS_2003 512
|
||||
#define FIELD_BYTES_2003 64
|
||||
|
||||
#define SHA_MSG_LENGTH_XP (4 + 2 * FIELD_BYTES)
|
||||
#define SHA_MSG_LENGTH_2003 (3 + 2 * FIELD_BYTES_2003)
|
||||
|
||||
#define NEXTSNBITS(field, n, offset) (((QWORD)(field) >> (offset)) & ((1ULL << (n)) - 1))
|
||||
#define FIRSTNBITS(field, n) NEXTSNBITS((field), (n), 0)
|
||||
|
||||
#define HIBYTES(field, bytes) NEXTSNBITS((QWORD)(field), ((bytes) * 8), ((bytes) * 8))
|
||||
#define LOBYTES(field, bytes) FIRSTNBITS((QWORD)(field), ((bytes) * 8))
|
||||
|
||||
#define BYDWORD(n) (DWORD)(*((n) + 0) | *((n) + 1) << 8 | *((n) + 2) << 16 | *((n) + 3) << 24)
|
||||
#define BITMASK(n) ((1ULL << (n)) - 1)
|
||||
|
||||
class UMSKT {
|
||||
public:
|
||||
static std::FILE* debug;
|
||||
class PIDGEN2;
|
||||
class PIDGEN3;
|
||||
class ConfigurationID;
|
||||
|
||||
static void setDebugOutput(std::FILE* input);
|
||||
};
|
||||
|
||||
|
||||
#endif //UMSKT_LIBUMSKT_H
|
||||
135
src/libumskt/pidgen2/PIDGEN2.cpp
Normal file
135
src/libumskt/pidgen2/PIDGEN2.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 06/17/2023
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#include "PIDGEN2.h"
|
||||
|
||||
const char* channelIDBlacklist [7] = {"333", "444", "555", "666", "777", "888", "999"};
|
||||
const char* validYears[8] = { "95", "96", "97", "98", "99", "00", "01", "02"};
|
||||
|
||||
bool PIDGEN2::isNumericString(char* input) {
|
||||
for(int i = 0; i < strlen(input); i++) {
|
||||
if (input[i] < '0' || input[i] > '9') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int PIDGEN2::addDigits(char* input) {
|
||||
int output = 0;
|
||||
|
||||
if (!isNumericString(input)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(int i = 0; i < strlen(input); i++) {
|
||||
output += input[i] - '0';
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
bool PIDGEN2::isValidChannelID(char* channelID) {
|
||||
if (strlen(channelID) > 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i <= 6; i++) {
|
||||
if (strcmp(channelID, channelIDBlacklist[i]) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PIDGEN2::isValidOEMID(char* OEMID) {
|
||||
if (!isNumericString(OEMID)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen(OEMID) > 5) {
|
||||
if (OEMID[0] != '0' || OEMID[1] != '0') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int mod = addDigits(OEMID);
|
||||
|
||||
return (mod % 21 == 0);
|
||||
}
|
||||
|
||||
bool PIDGEN2::isValidYear(char* year) {
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
if (year == validYears[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PIDGEN2::isValidDay(char* day) {
|
||||
if (!isNumericString(day)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int iDay = std::stoi(day);
|
||||
if (iDay == 0 || iDay >= 365) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PIDGEN2::isValidRetailProductID(char* productID) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int PIDGEN2::GenerateRetail(char* channelID, char* &keyout) {
|
||||
if (!isValidChannelID(channelID)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PIDGEN2::GenerateOEM(char* year, char* day, char* oem, char* &keyout) {
|
||||
if (!isValidOEMID(oem)) {
|
||||
int mod = addDigits(oem);
|
||||
mod += mod % 21;
|
||||
|
||||
strcpy(oem, fmt::format("{:07d}", mod).c_str());
|
||||
}
|
||||
|
||||
if (!isValidYear(year)) {
|
||||
strcpy(year, validYears[0]);
|
||||
}
|
||||
|
||||
if (!isValidDay(day)) {
|
||||
int iday = std::stoi(day);
|
||||
iday = (iday + 1) % 365;
|
||||
}
|
||||
|
||||
strcpy(keyout, fmt::format("{}{}-OEM-{}-{}", year, day, oem, oem).c_str());
|
||||
|
||||
return 0;
|
||||
}
|
||||
41
src/libumskt/pidgen2/PIDGEN2.h
Normal file
41
src/libumskt/pidgen2/PIDGEN2.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 06/17/2023
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#ifndef UMSKT_PIDGEN2_H
|
||||
#define UMSKT_PIDGEN2_H
|
||||
|
||||
#include "../libumskt.h"
|
||||
|
||||
EXPORT class PIDGEN2 {
|
||||
public:
|
||||
static bool isNumericString(char* input);
|
||||
static bool isValidChannelID(char* channelID);
|
||||
static bool isValidOEMID(char* OEMID);
|
||||
static bool isValidYear(char* year);
|
||||
static bool isValidDay(char* day);
|
||||
static bool isValidRetailProductID(char* productID);
|
||||
static int addDigits(char* input);
|
||||
static int GenerateRetail(char* channelID, char* &keyout);
|
||||
static int GenerateOEM(char* year, char* day, char* oem, char* &keyout);
|
||||
};
|
||||
|
||||
#endif //UMSKT_PIDGEN2_H
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "BINK1998.h"
|
||||
|
||||
/* Unpacks a Windows XP-like Product Key. */
|
||||
void BINK1998::Unpack(
|
||||
void PIDGEN3::BINK1998::Unpack(
|
||||
QWORD (&pRaw)[2],
|
||||
BOOL &pUpgrade,
|
||||
DWORD &pSerial,
|
||||
@@ -54,7 +54,7 @@ void BINK1998::Unpack(
|
||||
}
|
||||
|
||||
/* Packs a Windows XP-like Product Key. */
|
||||
void BINK1998::Pack(
|
||||
void PIDGEN3::BINK1998::Pack(
|
||||
QWORD (&pRaw)[2],
|
||||
BOOL pUpgrade,
|
||||
DWORD pSerial,
|
||||
@@ -71,7 +71,7 @@ void BINK1998::Pack(
|
||||
}
|
||||
|
||||
/* Verifies a Windows XP-like Product Key. */
|
||||
bool BINK1998::Verify(
|
||||
bool PIDGEN3::BINK1998::Verify(
|
||||
EC_GROUP *eCurve,
|
||||
EC_POINT *basePoint,
|
||||
EC_POINT *publicKey,
|
||||
@@ -89,19 +89,17 @@ bool BINK1998::Verify(
|
||||
BOOL pUpgrade;
|
||||
|
||||
// Convert Base24 CD-key to bytecode.
|
||||
unbase24((BYTE *)pRaw, pKey);
|
||||
PIDGEN3::unbase24((BYTE *)pRaw, pKey);
|
||||
|
||||
// Extract RPK, hash and signature from bytecode.
|
||||
Unpack(pRaw, pUpgrade, pSerial, pHash, pSignature);
|
||||
|
||||
if (options.verbose) {
|
||||
fmt::print("Validation results:\n");
|
||||
fmt::print(" Upgrade: 0x{:08x}\n", pUpgrade);
|
||||
fmt::print(" Serial: 0x{:08x}\n", pSerial);
|
||||
fmt::print(" Hash: 0x{:08x}\n", pHash);
|
||||
fmt::print(" Signature: 0x{:08x}\n", pSignature);
|
||||
fmt::print("\n");
|
||||
}
|
||||
fmt::print(UMSKT::debug, "Validation results:\n");
|
||||
fmt::print(UMSKT::debug, " Upgrade: 0x{:08x}\n", pUpgrade);
|
||||
fmt::print(UMSKT::debug, " Serial: 0x{:08x}\n", pSerial);
|
||||
fmt::print(UMSKT::debug, " Hash: 0x{:08x}\n", pHash);
|
||||
fmt::print(UMSKT::debug, " Signature: 0x{:08x}\n", pSignature);
|
||||
fmt::print(UMSKT::debug, "\n");
|
||||
|
||||
pData = pSerial << 1 | pUpgrade;
|
||||
|
||||
@@ -177,7 +175,7 @@ bool BINK1998::Verify(
|
||||
}
|
||||
|
||||
/* Generates a Windows XP-like Product Key. */
|
||||
void BINK1998::Generate(
|
||||
void PIDGEN3::BINK1998::Generate(
|
||||
EC_GROUP *eCurve,
|
||||
EC_POINT *basePoint,
|
||||
BIGNUM *genOrder,
|
||||
@@ -266,14 +264,12 @@ void BINK1998::Generate(
|
||||
// Pack product key.
|
||||
Pack(pRaw, pUpgrade, pSerial, pHash, pSignature);
|
||||
|
||||
if (options.verbose) {
|
||||
fmt::print("Generation results:\n");
|
||||
fmt::print(" Upgrade: 0x{:08x}\n", pUpgrade);
|
||||
fmt::print(" Serial: 0x{:08x}\n", pSerial);
|
||||
fmt::print(" Hash: 0x{:08x}\n", pHash);
|
||||
fmt::print(" Signature: 0x{:08x}\n", pSignature);
|
||||
fmt::print("\n");
|
||||
}
|
||||
fmt::print(UMSKT::debug, "Generation results:\n");
|
||||
fmt::print(UMSKT::debug, " Upgrade: 0x{:08x}\n", pUpgrade);
|
||||
fmt::print(UMSKT::debug, " Serial: 0x{:08x}\n", pSerial);
|
||||
fmt::print(UMSKT::debug, " Hash: 0x{:08x}\n", pHash);
|
||||
fmt::print(UMSKT::debug, " Signature: 0x{:08x}\n", pSignature);
|
||||
fmt::print(UMSKT::debug, "\n");
|
||||
|
||||
EC_POINT_free(r);
|
||||
} while (pSignature > BITMASK(55));
|
||||
@@ -290,4 +286,4 @@ void BINK1998::Generate(
|
||||
BN_free(y);
|
||||
|
||||
BN_CTX_free(numContext);
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,10 @@
|
||||
#ifndef UMSKT_BINK1998_H
|
||||
#define UMSKT_BINK1998_H
|
||||
|
||||
#include "header.h"
|
||||
#include "PIDGEN3.h"
|
||||
|
||||
class BINK1998 {
|
||||
EXPORT class PIDGEN3::BINK1998 {
|
||||
public:
|
||||
static void Unpack(
|
||||
QWORD (&pRaw)[2],
|
||||
BOOL &pUpgrade,
|
||||
@@ -33,6 +34,7 @@ class BINK1998 {
|
||||
DWORD &pHash,
|
||||
QWORD &pSignature
|
||||
);
|
||||
|
||||
static void Pack(
|
||||
QWORD (&pRaw)[2],
|
||||
BOOL pUpgrade,
|
||||
@@ -41,13 +43,13 @@ class BINK1998 {
|
||||
QWORD pSignature
|
||||
);
|
||||
|
||||
public:
|
||||
static bool Verify(
|
||||
EC_GROUP *eCurve,
|
||||
EC_POINT *basePoint,
|
||||
EC_POINT *publicKey,
|
||||
char (&pKey)[25]
|
||||
);
|
||||
|
||||
static void Generate(
|
||||
EC_GROUP *eCurve,
|
||||
EC_POINT *basePoint,
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "BINK2002.h"
|
||||
|
||||
/* Unpacks a Windows Server 2003-like Product Key. */
|
||||
void BINK2002::Unpack(
|
||||
void PIDGEN3::BINK2002::Unpack(
|
||||
QWORD (&pRaw)[2],
|
||||
BOOL &pUpgrade,
|
||||
DWORD &pChannelID,
|
||||
@@ -60,7 +60,7 @@ void BINK2002::Unpack(
|
||||
}
|
||||
|
||||
/* Packs a Windows Server 2003-like Product Key. */
|
||||
void BINK2002::Pack(
|
||||
void PIDGEN3::BINK2002::Pack(
|
||||
QWORD (&pRaw)[2],
|
||||
BOOL pUpgrade,
|
||||
DWORD pChannelID,
|
||||
@@ -74,7 +74,7 @@ void BINK2002::Pack(
|
||||
}
|
||||
|
||||
/* Verifies a Windows Server 2003-like Product Key. */
|
||||
bool BINK2002::Verify(
|
||||
bool PIDGEN3::BINK2002::Verify(
|
||||
EC_GROUP *eCurve,
|
||||
EC_POINT *basePoint,
|
||||
EC_POINT *publicKey,
|
||||
@@ -100,15 +100,13 @@ bool BINK2002::Verify(
|
||||
|
||||
pData = pChannelID << 1 | pUpgrade;
|
||||
|
||||
if (options.verbose) {
|
||||
fmt::print("Validation results:\n");
|
||||
fmt::print(" Upgrade: 0x{:08x}\n", pUpgrade);
|
||||
fmt::print("Channel ID: 0x{:08x}\n", pChannelID);
|
||||
fmt::print(" Hash: 0x{:08x}\n", pHash);
|
||||
fmt::print(" Signature: 0x{:08x}\n", pSignature);
|
||||
fmt::print(" AuthInfo: 0x{:08x}\n", pAuthInfo);
|
||||
fmt::print("\n");
|
||||
}
|
||||
fmt::print(UMSKT::debug, "Validation results:\n");
|
||||
fmt::print(UMSKT::debug, " Upgrade: 0x{:08x}\n", pUpgrade);
|
||||
fmt::print(UMSKT::debug, "Channel ID: 0x{:08x}\n", pChannelID);
|
||||
fmt::print(UMSKT::debug, " Hash: 0x{:08x}\n", pHash);
|
||||
fmt::print(UMSKT::debug, " Signature: 0x{:08x}\n", pSignature);
|
||||
fmt::print(UMSKT::debug, " AuthInfo: 0x{:08x}\n", pAuthInfo);
|
||||
fmt::print(UMSKT::debug, "\n");
|
||||
|
||||
BYTE msgDigest[SHA_DIGEST_LENGTH]{},
|
||||
msgBuffer[SHA_MSG_LENGTH_2003]{},
|
||||
@@ -208,7 +206,7 @@ bool BINK2002::Verify(
|
||||
}
|
||||
|
||||
/* Generates a Windows Server 2003-like Product Key. */
|
||||
void BINK2002::Generate(
|
||||
void PIDGEN3::BINK2002::Generate(
|
||||
EC_GROUP *eCurve,
|
||||
EC_POINT *basePoint,
|
||||
BIGNUM *genOrder,
|
||||
@@ -361,15 +359,13 @@ void BINK2002::Generate(
|
||||
// Pack product key.
|
||||
Pack(pRaw, pUpgrade, pChannelID, pHash, pSignature, pAuthInfo);
|
||||
|
||||
if (options.verbose) {
|
||||
fmt::print("Generation results:\n");
|
||||
fmt::print(" Upgrade: 0x{:08x}\n", pUpgrade);
|
||||
fmt::print("Channel ID: 0x{:08x}\n", pChannelID);
|
||||
fmt::print(" Hash: 0x{:08x}\n", pHash);
|
||||
fmt::print(" Signature: 0x{:08x}\n", pSignature);
|
||||
fmt::print(" AuthInfo: 0x{:08x}\n", pAuthInfo);
|
||||
fmt::print("\n");
|
||||
}
|
||||
fmt::print(UMSKT::debug, "Generation results:\n");
|
||||
fmt::print(UMSKT::debug, " Upgrade: 0x{:08x}\n", pUpgrade);
|
||||
fmt::print(UMSKT::debug, "Channel ID: 0x{:08x}\n", pChannelID);
|
||||
fmt::print(UMSKT::debug, " Hash: 0x{:08x}\n", pHash);
|
||||
fmt::print(UMSKT::debug, " Signature: 0x{:08x}\n", pSignature);
|
||||
fmt::print(UMSKT::debug, " AuthInfo: 0x{:08x}\n", pAuthInfo);
|
||||
fmt::print(UMSKT::debug, "\n");
|
||||
|
||||
EC_POINT_free(r);
|
||||
} while (pSignature > BITMASK(62) || noSquare);
|
||||
@@ -387,4 +383,4 @@ void BINK2002::Generate(
|
||||
BN_free(e);
|
||||
|
||||
BN_CTX_free(numContext);
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,10 @@
|
||||
#ifndef UMSKT_BINK2002_H
|
||||
#define UMSKT_BINK2002_H
|
||||
|
||||
#include "header.h"
|
||||
#include "PIDGEN3.h"
|
||||
|
||||
class BINK2002 {
|
||||
EXPORT class PIDGEN3::BINK2002 {
|
||||
public:
|
||||
static void Unpack(
|
||||
QWORD (&pRaw)[2],
|
||||
BOOL &pUpgrade,
|
||||
@@ -34,6 +35,7 @@ class BINK2002 {
|
||||
QWORD &pSignature,
|
||||
DWORD &pAuthInfo
|
||||
);
|
||||
|
||||
static void Pack(
|
||||
QWORD (&pRaw)[2],
|
||||
BOOL pUpgrade,
|
||||
@@ -43,13 +45,13 @@ class BINK2002 {
|
||||
DWORD pAuthInfo
|
||||
);
|
||||
|
||||
public:
|
||||
static bool Verify(
|
||||
EC_GROUP *eCurve,
|
||||
EC_POINT *basePoint,
|
||||
EC_POINT *publicKey,
|
||||
char (&cdKey)[25]
|
||||
);
|
||||
|
||||
static void Generate(
|
||||
EC_GROUP *eCurve,
|
||||
EC_POINT *basePoint,
|
||||
54
src/libumskt/pidgen3/PIDGEN3.h
Normal file
54
src/libumskt/pidgen3/PIDGEN3.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 6/24/2023
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#ifndef UMSKT_PIDGEN3_H
|
||||
#define UMSKT_PIDGEN3_H
|
||||
|
||||
#include "../libumskt.h"
|
||||
|
||||
class PIDGEN3 {
|
||||
public:
|
||||
class BINK1998;
|
||||
class BINK2002;
|
||||
|
||||
// util.cpp
|
||||
static int BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen); // Hello OpenSSL developers, please tell me, where is this function at?
|
||||
static void endian(BYTE *data, int length);
|
||||
static EC_GROUP* initializeEllipticCurve(
|
||||
std::string pSel,
|
||||
std::string aSel,
|
||||
std::string bSel,
|
||||
std::string generatorXSel,
|
||||
std::string generatorYSel,
|
||||
std::string publicKeyXSel,
|
||||
std::string publicKeyYSel,
|
||||
EC_POINT *&genPoint,
|
||||
EC_POINT *&pubPoint
|
||||
);
|
||||
|
||||
// key.cpp
|
||||
static constexpr char pKeyCharset[] = "BCDFGHJKMPQRTVWXY2346789";
|
||||
static void unbase24(BYTE *byteSeq, const char *cdKey);
|
||||
static void base24(char *cdKey, BYTE *byteSeq);
|
||||
};
|
||||
|
||||
#endif //UMSKT_PIDGEN3_H
|
||||
@@ -20,13 +20,10 @@
|
||||
* @Maintainer Andrew
|
||||
*/
|
||||
|
||||
#include "header.h"
|
||||
|
||||
/* The allowed character set in a product key. */
|
||||
char pKeyCharset[] = "BCDFGHJKMPQRTVWXY2346789";
|
||||
#include "PIDGEN3.h"
|
||||
|
||||
/* Converts from CD-key to a byte sequence. */
|
||||
void unbase24(BYTE *byteSeq, const char *cdKey) {
|
||||
void PIDGEN3::unbase24(BYTE *byteSeq, const char *cdKey) {
|
||||
BYTE pDecodedKey[PK_LENGTH + NULL_TERMINATOR]{};
|
||||
BIGNUM *y = BN_new();
|
||||
|
||||
@@ -63,7 +60,7 @@ void unbase24(BYTE *byteSeq, const char *cdKey) {
|
||||
}
|
||||
|
||||
/* Converts from byte sequence to the CD-key. */
|
||||
void base24(char *cdKey, BYTE *byteSeq) {
|
||||
void PIDGEN3::base24(char *cdKey, BYTE *byteSeq) {
|
||||
BYTE rbyteSeq[16];
|
||||
BIGNUM *z;
|
||||
|
||||
@@ -86,4 +83,4 @@ void base24(char *cdKey, BYTE *byteSeq) {
|
||||
cdKey[i] = pKeyCharset[BN_div_word(z, 24)];
|
||||
|
||||
BN_free(z);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
* @Maintainer Andrew
|
||||
*/
|
||||
|
||||
#include "header.h"
|
||||
#include "PIDGEN3.h"
|
||||
|
||||
int randomRange() {
|
||||
return 4; // chosen by fair dice roll
|
||||
@@ -28,7 +28,7 @@ int randomRange() {
|
||||
}
|
||||
|
||||
/* Convert data between endianness types. */
|
||||
void endian(BYTE *data, int length) {
|
||||
void PIDGEN3::endian(BYTE *data, int length) {
|
||||
for (int i = 0; i < length / 2; i++) {
|
||||
BYTE temp = data[i];
|
||||
data[i] = data[length - i - 1];
|
||||
@@ -37,7 +37,7 @@ void endian(BYTE *data, int length) {
|
||||
}
|
||||
|
||||
/* Initializes the elliptic curve. */
|
||||
EC_GROUP *initializeEllipticCurve(
|
||||
EC_GROUP* PIDGEN3::initializeEllipticCurve(
|
||||
const std::string pSel,
|
||||
const std::string aSel,
|
||||
const std::string bSel,
|
||||
@@ -104,7 +104,7 @@ EC_GROUP *initializeEllipticCurve(
|
||||
return eCurve;
|
||||
}
|
||||
|
||||
int BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen) {
|
||||
int PIDGEN3::BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen) {
|
||||
if (a == nullptr || to == nullptr)
|
||||
return 0;
|
||||
|
||||
@@ -117,4 +117,4 @@ int BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen) {
|
||||
endian(to, tolen);
|
||||
|
||||
return len;
|
||||
}
|
||||
}
|
||||
59
src/typedefs.h
Normal file
59
src/typedefs.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 6/24/2023
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#ifndef UMSKT_TYPEDEFS_H
|
||||
#define UMSKT_TYPEDEFS_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdbool>
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <cassert>
|
||||
#else
|
||||
#define assert(x) /* nothing */
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define EXPORT extern "C" __declspec(dllexport)
|
||||
#else
|
||||
#define EXPORT extern "C"
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#define FNEXPORT EMSCRIPTEN_KEEPALIVE EXPORT
|
||||
#else
|
||||
#define FNEXPORT EXPORT
|
||||
#endif
|
||||
|
||||
// Type definitions
|
||||
typedef bool BOOL;
|
||||
typedef uint8_t BYTE;
|
||||
typedef uint16_t WORD;
|
||||
typedef uint32_t DWORD;
|
||||
typedef uint64_t QWORD;
|
||||
|
||||
#ifdef __SIZEOF_INT128__
|
||||
typedef unsigned __int128 OWORD;
|
||||
#endif
|
||||
|
||||
#endif //UMSKT_TYPEDEFS_H
|
||||
46
src/windows/dllmain.cpp
Normal file
46
src/windows/dllmain.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 06/17/2023
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
|
||||
BOOLEAN WINAPI DllMain( IN HINSTANCE hDllHandle,
|
||||
IN DWORD nReason,
|
||||
IN LPVOID Reserved ) {
|
||||
|
||||
BOOLEAN bSuccess = TRUE;
|
||||
// Perform global initialization.
|
||||
switch (nReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
// For optimization.
|
||||
DisableThreadLibraryCalls(hDllHandle);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// end DllMain
|
||||
BIN
src/windows/icon.ico
Normal file
BIN
src/windows/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
38
src/windows/resource.h
Normal file
38
src/windows/resource.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* This file is a part of the UMSKT Project
|
||||
*
|
||||
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @FileCreated by Neo on 6/17/2023
|
||||
* @Maintainer Neo
|
||||
*/
|
||||
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by umskt.rc
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
BIN
src/windows/umskt.rc
Normal file
BIN
src/windows/umskt.rc
Normal file
Binary file not shown.
Reference in New Issue
Block a user