Command line option to specify serial for generating BINK1998 keys (#33)

* specify pre-set serial on CLI for BINK1998

* fix CLI::printID
This commit is contained in:
Emma 2023-07-04 11:20:17 +01:00 committed by GitHub
parent 9817a83e74
commit de04746c5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 11 deletions

View File

@ -53,6 +53,7 @@ void CLI::showHelp(char *argv[]) {
fmt::print("\t-b --binkid\tspecify which BINK identifier to load (defaults to 2E)\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-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-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("\t-V --validate\tproduct key to validate signature\n");
fmt::print("\n\n"); fmt::print("\n\n");
} }
@ -64,6 +65,8 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) {
"", "",
"", "",
640, 640,
false,
0,
1, 1,
false, false,
false, false,
@ -116,6 +119,20 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) {
options->channelID = siteID; options->channelID = siteID;
} }
i++; i++;
} else if (arg == "-s" || arg == "--serial") {
if (i == argc - 1) {
options->error = true;
break;
}
int serial_val;
if (!sscanf(argv[i+1], "%d", &serial_val)) {
options->error = true;
} else {
options->serialSet = true;
options->serial = serial_val;
}
i++;
} else if (arg == "-f" || arg == "--file") { } else if (arg == "-f" || arg == "--file") {
if (i == argc - 1) { if (i == argc - 1) {
options->error = true; options->error = true;
@ -197,6 +214,12 @@ int CLI::validateCommandLine(Options* options, char *argv[], json *keys) {
return 1; return 1;
} }
// don't allow any serial not between 0 and 999999
if (options->serial > 999999 || options->serial < 0) {
fmt::print("ERROR: refusing to create a key with a Serial not between 000000 and 999999\n");
return 1;
}
return 0; return 0;
} }
@ -206,8 +229,8 @@ void CLI::printID(DWORD *pid)
char b[6], c[8]; char b[6], c[8];
int i, digit = 0; int i, digit = 0;
// Cut away last bit of pid and convert it to an accii-number (=raw) // Convert PID to ascii-number (=raw)
sprintf(raw, "%iu", pid[0] >> 1); sprintf(raw, "%09u", pid[0]);
// Make b-part {640-....} // Make b-part {640-....}
strncpy(b, raw, 3); strncpy(b, raw, 3);
@ -215,7 +238,6 @@ void CLI::printID(DWORD *pid)
// Make c-part {...-123456X...} // Make c-part {...-123456X...}
strcpy(c, raw + 3); strcpy(c, raw + 3);
fmt::print("> {}\n", c);
// Make checksum digit-part {...56X-} // Make checksum digit-part {...56X-}
assert(strlen(c) == 6); assert(strlen(c) == 6);
@ -227,7 +249,7 @@ void CLI::printID(DWORD *pid)
c[6] = digit + '0'; c[6] = digit + '0';
c[7] = 0; c[7] = 0;
fmt::print("Product ID: PPPPP-{}-{}-23xxx\n", b, c); fmt::print("> Product ID: PPPPP-{}-{}-23xxx\n", b, c);
} }
void CLI::printKey(char *pk) { void CLI::printKey(char *pk) {
@ -316,19 +338,30 @@ CLI::CLI(Options options, json keys) {
} }
int CLI::BINK1998Generate() { int CLI::BINK1998Generate() {
// raw PID/serial value
DWORD nRaw = this->options.channelID * 1'000'000 ; /* <- change */ DWORD nRaw = this->options.channelID * 1'000'000 ; /* <- change */
BIGNUM *bnrand = BN_new(); // using user-provided serial
BN_rand(bnrand, 19, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY); if (this->options.serialSet) {
// just in case, make sure it's less than 999999
int serialRnd = (this->options.serial % 999999);
nRaw += serialRnd;
} else {
// generate a random number to use as a serial
BIGNUM *bnrand = BN_new();
BN_rand(bnrand, 19, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY);
int oRaw; int oRaw;
char *cRaw = BN_bn2dec(bnrand); char *cRaw = BN_bn2dec(bnrand);
sscanf(cRaw, "%d", &oRaw); sscanf(cRaw, "%d", &oRaw);
nRaw += (oRaw % 999999); // ensure our serial is less than 999999 nRaw += (oRaw % 999999); // ensure our serial is less than 999999
}
if (this->options.verbose) { if (this->options.verbose) {
fmt::print("> PID: {:09d}\n", nRaw); // print the resulting Product ID
// PID value is printed in BINK1998::Generate
printID(&nRaw);
} }
// generate a key // generate a key

View File

@ -89,6 +89,8 @@ struct Options {
std::string instid; std::string instid;
std::string keyToCheck; std::string keyToCheck;
int channelID; int channelID;
bool serialSet;
int serial;
int numKeys; int numKeys;
bool verbose; bool verbose;
bool help; bool help;