mirror of
https://github.com/Neo-Desktop/WindowsXPKg
synced 2026-05-16 22:45:03 +03:00
Merge pull request #180 from UMSKT/bink2002serial
Implement BINK2002 serial range specification and serial range argument
This commit is contained in:
@@ -109,10 +109,13 @@ jobs:
|
||||
cat > dosbox_test/test.bat << EOL
|
||||
@echo off
|
||||
echo Running test 1...
|
||||
umskt.exe -b 2C -c 365 -s 069420 > TEST1.TXT
|
||||
umskt.exe -b 2C -c 365 -s 069420,999999 > TEST1.TXT
|
||||
if errorlevel 1 goto error
|
||||
echo Running test 2...
|
||||
umskt.exe -i 253286028742154311079061239762245184619981623171292574 > TEST2.TXT
|
||||
umskt.exe -b 5A -c 640 -s 069420,999999 > TEST2.TXT
|
||||
if errorlevel 1 goto error
|
||||
echo Running test 3...
|
||||
umskt.exe -i 253286028742154311079061239762245184619981623171292574 > TEST3.TXT
|
||||
if errorlevel 1 goto error
|
||||
echo Tests completed > DONE.TXT
|
||||
goto end
|
||||
@@ -154,21 +157,28 @@ jobs:
|
||||
echo "Test 2 output:"
|
||||
cat TEST2.TXT
|
||||
fi
|
||||
if [ -f TEST3.TXT ]; then
|
||||
echo "Test 3 output:"
|
||||
cat TEST3.TXT
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
# Verify test outputs
|
||||
if [ ! -f TEST1.TXT ] || [ ! -f TEST2.TXT ]; then
|
||||
if [ ! -f TEST1.TXT ] || [ ! -f TEST2.TXT ] || [ ! -f TEST3.TXT ]; then
|
||||
echo "Test output files missing"
|
||||
exit 1
|
||||
fi
|
||||
# Check test results - looking for key format patterns
|
||||
if ! grep -qE '[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}' TEST1.TXT || \
|
||||
! grep -qE '[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}' TEST2.TXT; then
|
||||
! grep -qE '[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}' TEST2.TXT || \
|
||||
! grep -qE '[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}' TEST3.TXT; then
|
||||
echo "Tests failed - unexpected output format"
|
||||
echo "Test 1 output:"
|
||||
cat TEST1.TXT
|
||||
echo "Test 2 output:"
|
||||
cat TEST2.TXT
|
||||
echo "Test 3 output:"
|
||||
cat TEST3.txt
|
||||
exit 1
|
||||
else
|
||||
echo "All tests passed successfully"
|
||||
@@ -176,6 +186,8 @@ jobs:
|
||||
cat TEST1.TXT
|
||||
echo "Test 2 output:"
|
||||
cat TEST2.TXT
|
||||
echo "Test 3 output:"
|
||||
cat TEST3.TXT
|
||||
fi
|
||||
|
||||
- name: Move executable to upload directory
|
||||
@@ -226,10 +238,13 @@ jobs:
|
||||
cat > dosbox_test/test.bat << EOL
|
||||
@echo off
|
||||
echo Running test 1...
|
||||
umskt.exe -b 2C -c 365 -s 069420 > TEST1.TXT
|
||||
umskt.exe -b 2C -c 365 -s 069420,999999 > TEST1.TXT
|
||||
if errorlevel 1 goto error
|
||||
echo Running test 2...
|
||||
umskt.exe -i 253286028742154311079061239762245184619981623171292574 > TEST2.TXT
|
||||
umskt.exe -b 5A -c 640 -s 069420,999999 > TEST2.TXT
|
||||
if errorlevel 1 goto error
|
||||
echo Running test 3...
|
||||
umskt.exe -i 253286028742154311079061239762245184619981623171292574 > TEST3.TXT
|
||||
if errorlevel 1 goto error
|
||||
echo Tests completed > DONE.TXT
|
||||
goto end
|
||||
@@ -272,21 +287,28 @@ jobs:
|
||||
echo "Test 2 output:"
|
||||
cat TEST2.TXT
|
||||
fi
|
||||
if [ -f TEST3.TXT ]; then
|
||||
echo "Test 3 output:"
|
||||
cat TEST3.TXT
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
# Verify test outputs
|
||||
if [ ! -f TEST1.TXT ] || [ ! -f TEST2.TXT ]; then
|
||||
if [ ! -f TEST1.TXT ] || [ ! -f TEST2.TXT ] || [ ! -f TEST3.TXT ]; then
|
||||
echo "Test output files missing"
|
||||
exit 1
|
||||
fi
|
||||
# Check test results - looking for key format patterns
|
||||
if ! grep -qE '[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}' TEST1.TXT || \
|
||||
! grep -qE '[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}' TEST2.TXT; then
|
||||
! grep -qE '[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}' TEST2.TXT || \
|
||||
! grep -qE '[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}-[0-9]{6}' TEST3.TXT; then
|
||||
echo "Tests failed - unexpected output format"
|
||||
echo "Test 1 output:"
|
||||
cat TEST1.TXT
|
||||
echo "Test 2 output:"
|
||||
cat TEST2.TXT
|
||||
echo "Test 3 output:"
|
||||
cat TEST3.txt
|
||||
exit 1
|
||||
else
|
||||
echo "All tests passed successfully"
|
||||
@@ -294,6 +316,8 @@ jobs:
|
||||
cat TEST1.TXT
|
||||
echo "Test 2 output:"
|
||||
cat TEST2.TXT
|
||||
echo "Test 3 output:"
|
||||
cat TEST3.TXT
|
||||
fi
|
||||
|
||||
- name: Move executable to upload directory
|
||||
|
||||
@@ -51,8 +51,10 @@
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
echo Test 1 - generating key
|
||||
./umskt -b 2C -c 365 -s 069420 -v
|
||||
echo Test 1 - generating key (BINK1998)
|
||||
./umskt -b 2C -c 365 -s 069420,999999 -v
|
||||
echo Test 2 - generating key (BINK2002)
|
||||
./umskt -b 5A -c 640 -s 069420,999999 -v
|
||||
echo Test 2 - generating confid
|
||||
./umskt -i 253286028742154311079061239762245184619981623171292574
|
||||
|
||||
|
||||
+30
-18
@@ -86,9 +86,11 @@ jobs:
|
||||
if: ${{ matrix.use_alpine }}
|
||||
run: |
|
||||
cd build
|
||||
echo Test 1 - generating key
|
||||
./umskt -b 2C -c 365 -s 069420 -v
|
||||
echo Test 2 - generating confid
|
||||
echo Test 1 - generating key \(BINK1998\)
|
||||
./umskt -b 2C -c 365 -s 069420,999999 -v
|
||||
echo Test 2 - generating key \(BINK2002\)
|
||||
./umskt -b 5A -c 640 -s 069420,999999 -v
|
||||
echo Test 3 - generating confid
|
||||
./umskt -i 253286028742154311079061239762245184619981623171292574
|
||||
shell: alpine-target.sh {0}
|
||||
|
||||
@@ -96,9 +98,11 @@ jobs:
|
||||
if: ${{ !matrix.use_alpine }}
|
||||
run: |
|
||||
cd build
|
||||
echo Test 1 - generating key
|
||||
./umskt -b 2C -c 365 -s 069420 -v
|
||||
echo Test 2 - generating confid
|
||||
echo Test 1 - generating key \(BINK1998\)
|
||||
./umskt -b 2C -c 365 -s 069420,999999 -v
|
||||
echo Test 2 - generating key \(BINK2002\)
|
||||
./umskt -b 5A -c 640 -s 069420,999999 -v
|
||||
echo Test 3 - generating confid
|
||||
./umskt -i 253286028742154311079061239762245184619981623171292574
|
||||
|
||||
- name: Move files to correct directory
|
||||
@@ -131,9 +135,11 @@ jobs:
|
||||
if: ${{ matrix.use_alpine }}
|
||||
run: |
|
||||
cd build
|
||||
echo Test 1 - generating key
|
||||
./umskt -b 2C -c 365 -s 069420 -v
|
||||
echo Test 2 - generating confid
|
||||
echo Test 1 - generating key \(BINK1998\)
|
||||
./umskt -b 2C -c 365 -s 069420,999999 -v
|
||||
echo Test 2 - generating key \(BINK2002\)
|
||||
./umskt -b 5A -c 640 -s 069420,999999 -v
|
||||
echo Test 3 - generating confid
|
||||
./umskt -i 253286028742154311079061239762245184619981623171292574
|
||||
shell: alpine-target.sh {0}
|
||||
|
||||
@@ -141,9 +147,11 @@ jobs:
|
||||
if: ${{ !matrix.use_alpine }}
|
||||
run: |
|
||||
cd build
|
||||
echo Test 1 - generating key
|
||||
./umskt -b 2C -c 365 -s 069420 -v
|
||||
echo Test 2 - generating confid
|
||||
echo Test 1 - generating key \(BINK1998\)
|
||||
./umskt -b 2C -c 365 -s 069420,999999 -v
|
||||
echo Test 2 - generating key \(BINK2002\)
|
||||
./umskt -b 5A -c 640 -s 069420,999999 -v
|
||||
echo Test 3 - generating confid
|
||||
./umskt -i 253286028742154311079061239762245184619981623171292574
|
||||
|
||||
- name: Configure and build shared deps UMSKT (Alpine)
|
||||
@@ -165,9 +173,11 @@ jobs:
|
||||
if: ${{ matrix.use_alpine }}
|
||||
run: |
|
||||
cd build
|
||||
echo Test 1 - generating key
|
||||
./umskt -b 2C -c 365 -s 069420 -v
|
||||
echo Test 2 - generating confid
|
||||
echo Test 1 - generating key \(BINK1998\)
|
||||
./umskt -b 2C -c 365 -s 069420,999999 -v
|
||||
echo Test 2 - generating key \(BINK2002\)
|
||||
./umskt -b 5A -c 640 -s 069420,999999 -v
|
||||
echo Test 3 - generating confid
|
||||
./umskt -i 253286028742154311079061239762245184619981623171292574
|
||||
shell: alpine-target.sh {0}
|
||||
|
||||
@@ -175,7 +185,9 @@ jobs:
|
||||
if: ${{ !matrix.use_alpine }}
|
||||
run: |
|
||||
cd build
|
||||
echo Test 1 - generating key
|
||||
./umskt -b 2C -c 365 -s 069420 -v
|
||||
echo Test 2 - generating confid
|
||||
echo Test 1 - generating key \(BINK1998\)
|
||||
./umskt -b 2C -c 365 -s 069420,999999 -v
|
||||
echo Test 2 - generating key \(BINK2002\)
|
||||
./umskt -b 5A -c 640 -s 069420,999999 -v
|
||||
echo Test 3 - generating confid
|
||||
./umskt -i 253286028742154311079061239762245184619981623171292574
|
||||
|
||||
@@ -86,9 +86,11 @@ jobs:
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd build/actions_upload
|
||||
echo Test 1 - generating key
|
||||
./umskt -b 2C -c 365 -s 069420 -v
|
||||
echo Test 2 - generating confid
|
||||
echo Test 1 - generating key \(BINK1998\)
|
||||
./umskt -b 2C -c 365 -s 069420,999999 -v
|
||||
echo Test 2 - generating key \(BINK2002\)
|
||||
./umskt -b 5A -c 640 -s 069420,999999 -v
|
||||
echo Test 3 - generating confid
|
||||
./umskt -i 253286028742154311079061239762245184619981623171292574
|
||||
|
||||
- name: Upload platform-specific build
|
||||
|
||||
@@ -138,7 +138,9 @@ jobs:
|
||||
- name: Run tests
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Host Test 1 - generating key
|
||||
.\umskt.exe -b 2C -c 365 -s 069420 -v
|
||||
Write-Host Test 2 - generatng confid
|
||||
Write-Host Test 1 - generating key `(BINK1998`)
|
||||
.\umskt.exe -b 2C -c 365 -s 069420,999999 -v
|
||||
Write-Host Test 2 - generating key `(BINK2002`)
|
||||
.\umskt.exe -b 5A -c 640 -s 069420,999999 -v
|
||||
Write-Host Test 3 - generatng confid
|
||||
.\umskt.exe -i 253286028742154311079061239762245184619981623171292574
|
||||
|
||||
@@ -223,9 +223,11 @@ jobs:
|
||||
- name: Run tests
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Host Test 1 - generating key
|
||||
.\umskt.exe -b 2C -c 365 -s 069420 -v
|
||||
Write-Host Test 2 - generatng confid
|
||||
Write-Host Test 1 - generating key `(BINK1998`)
|
||||
.\umskt.exe -b 2C -c 365 -s 069420,999999 -v
|
||||
Write-Host Test 2 - generating key `(BINK2002`)
|
||||
.\umskt.exe -b 5A -c 640 -s 069420,999999 -v
|
||||
Write-Host Test 3 - generatng confid
|
||||
.\umskt.exe -i 253286028742154311079061239762245184619981623171292574
|
||||
|
||||
- name: Upload build artifact
|
||||
|
||||
+30
-14
@@ -67,7 +67,7 @@ void CLI::showHelp(char *argv[]) {
|
||||
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-s --serial\tspecifies a serial (eg. 123456) or comma-separated serial range (recommended for BINK2002, eg. 1234,5678) to use in the product ID (defaults to 0,999999)\n");
|
||||
fmt::print("\t-u --upgrade\tspecifies the Product Key will be an \"Upgrade\" version\n");
|
||||
fmt::print("\t-V --validate\tproduct key to validate signature\n");
|
||||
fmt::print("\t-N --nonewlines\tdisables newlines (for easier embedding in other apps)\n");
|
||||
@@ -86,6 +86,7 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) {
|
||||
"",
|
||||
640,
|
||||
0,
|
||||
999999,
|
||||
1,
|
||||
false,
|
||||
false,
|
||||
@@ -149,12 +150,20 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) {
|
||||
break;
|
||||
}
|
||||
|
||||
int serial_val;
|
||||
if (!sscanf(argv[i+1], "%d", &serial_val)) {
|
||||
options->error = true;
|
||||
} else {
|
||||
int serial_min;
|
||||
int serial_max;
|
||||
if (strchr(argv[i+1], ',') && sscanf(argv[i + 1], "%d,%d", &serial_min, &serial_max)) {
|
||||
options->serialSet = true;
|
||||
options->serial = serial_val;
|
||||
options->serialMin = serial_min;
|
||||
options->serialMax = serial_max;
|
||||
}
|
||||
else if (sscanf(argv[i + 1], "%d", &serial_min)) {
|
||||
options->serialSet = true;
|
||||
options->serialMin = serial_min;
|
||||
options->serialMax = serial_min;
|
||||
}
|
||||
else {
|
||||
options->error = true;
|
||||
}
|
||||
i++;
|
||||
} else if (arg == "-u" || arg == "--upgrade") {
|
||||
@@ -293,10 +302,15 @@ int CLI::validateCommandLine(Options* options, char *argv[], json *keys) {
|
||||
}
|
||||
|
||||
// don't allow any serial not between 0 and 999999
|
||||
if (options->serial > 999999 || options->serial < 0) {
|
||||
if (options->serialMin > 999999 || options->serialMin < 0 || options->serialMax < 0 || options->serialMax > 999999) {
|
||||
fmt::print("ERROR: refusing to create a key with a Serial not between 000000 and 999999\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (options->serialMin > options->serialMax) {
|
||||
fmt::print("ERROR: serial minimum cannot be greater than serial maximum\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -429,11 +443,13 @@ CLI::CLI(Options options, json keys) {
|
||||
int CLI::BINK1998Generate() {
|
||||
// raw PID/serial value
|
||||
DWORD nRaw = this->options.channelID * 1'000'000 ; /* <- change */
|
||||
DWORD serMin = this->options.serialMin;
|
||||
DWORD serMax = this->options.serialMax;
|
||||
|
||||
// using user-provided serial
|
||||
if (this->options.serialSet) {
|
||||
if ((serMin == serMax) && this->options.serialSet) {
|
||||
// just in case, make sure it's less than 1000000
|
||||
int serialRnd = (this->options.serial % 1000000);
|
||||
int serialRnd = (this->options.serialMin % 1000000);
|
||||
nRaw += serialRnd;
|
||||
} else {
|
||||
// generate a random number to use as a serial
|
||||
@@ -444,8 +460,8 @@ int CLI::BINK1998Generate() {
|
||||
char *cRaw = BN_bn2dec(bnrand);
|
||||
|
||||
sscanf(cRaw, "%d", &oRaw);
|
||||
nRaw += (oRaw % 1000000); // ensure our serial is less than 1000000
|
||||
BN_free(bnrand);
|
||||
nRaw += serMin + (oRaw % (serMax - serMin + 1)); // ensure our serial is within specified range
|
||||
BN_free(bnrand);
|
||||
}
|
||||
|
||||
if (this->options.verbose) {
|
||||
@@ -506,9 +522,9 @@ int CLI::BINK2002Generate() {
|
||||
fmt::print("> AuthInfo: {}\n", pAuthInfo);
|
||||
}
|
||||
|
||||
PIDGEN3::BINK2002::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, pChannelID, pAuthInfo, options.upgrade, this->pKey);
|
||||
PIDGEN3::BINK2002::Generate(this->eCurve, this->genPoint, this->genOrder, this->privateKey, pChannelID, pAuthInfo, options.upgrade, this->options.serialMin, this->options.serialMax, this->pKey);
|
||||
|
||||
bool isValid = PIDGEN3::BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, this->pKey);
|
||||
bool isValid = PIDGEN3::BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, NULL, this->pKey);
|
||||
if (isValid) {
|
||||
CLI::printKey(this->pKey);
|
||||
if (i < this->total - 1 || this->options.verbose) { // check if end of list or verbose
|
||||
@@ -567,7 +583,7 @@ int CLI::BINK2002Validate() {
|
||||
|
||||
CLI::printKey(product_key);
|
||||
fmt::print("\n");
|
||||
if (!PIDGEN3::BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, product_key)) {
|
||||
if (!PIDGEN3::BINK2002::Verify(this->eCurve, this->genPoint, this->pubPoint, nullptr, product_key)) {
|
||||
fmt::print("ERROR: Product key is invalid! Wrong BINK ID?\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,8 @@ struct Options {
|
||||
std::string keyToCheck;
|
||||
std::string productid;
|
||||
int channelID;
|
||||
int serial;
|
||||
int serialMin;
|
||||
int serialMax;
|
||||
int numKeys;
|
||||
bool upgrade;
|
||||
bool serialSet;
|
||||
|
||||
@@ -43,12 +43,12 @@ FNEXPORT void PIDGEN3_BINK1998_Generate(EC_GROUP *eCurve, EC_POINT *basePoint, B
|
||||
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 bool PIDGEN3_BINK2002_Verify(EC_GROUP *eCurve, EC_POINT *basePoint, EC_POINT *publicKey, DWORD *pSerial, char (&cdKey)[25]) {
|
||||
return PIDGEN3::BINK2002::Verify(eCurve, basePoint, publicKey, pSerial, 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 void PIDGEN3_BINK2002_Generate(EC_GROUP *eCurve, EC_POINT *basePoint, BIGNUM *genOrder, BIGNUM *privateKey, DWORD pChannelID, DWORD pAuthInfo, BOOL pUpgrade, DWORD serMin, DWORD serMax, char (&pKey)[25]) {
|
||||
return PIDGEN3::BINK2002::Generate(eCurve, basePoint, genOrder, privateKey, pChannelID, pAuthInfo, pUpgrade, serMin, serMax, pKey);
|
||||
}
|
||||
|
||||
FNEXPORT int PIDGEN2_GenerateRetail(char* channelID, char* &keyout) {
|
||||
|
||||
@@ -78,6 +78,7 @@ bool PIDGEN3::BINK2002::Verify(
|
||||
EC_GROUP *eCurve,
|
||||
EC_POINT *basePoint,
|
||||
EC_POINT *publicKey,
|
||||
DWORD *pSerial,
|
||||
char (&cdKey)[25]
|
||||
) {
|
||||
BN_CTX *context = BN_CTX_new();
|
||||
@@ -100,14 +101,6 @@ bool PIDGEN3::BINK2002::Verify(
|
||||
|
||||
pData = pChannelID << 1 | pUpgrade;
|
||||
|
||||
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]{},
|
||||
xBin[FIELD_BYTES_2003]{},
|
||||
@@ -187,6 +180,18 @@ bool PIDGEN3::BINK2002::Verify(
|
||||
// compHash = SHA1(79 || Channel ID || p.x || p.y)
|
||||
SHA1(msgBuffer, SHA_MSG_LENGTH_2003, msgDigest);
|
||||
|
||||
DWORD serial = (((BYDWORD(msgDigest + 4) >> 13) << 1) | (BYDWORD(msgDigest) >> 31)) & BITMASK(20);
|
||||
if (pSerial != nullptr) *pSerial = serial;
|
||||
|
||||
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, " Serial: {:06d}\n", serial);
|
||||
fmt::print(UMSKT::debug, "\n");
|
||||
|
||||
// Translate the byte digest into a 32-bit integer - this is our computed hash.
|
||||
// Truncate the hash to 31 bits.
|
||||
DWORD compHash = BYDWORD(msgDigest) & BITMASK(31);
|
||||
@@ -214,6 +219,8 @@ void PIDGEN3::BINK2002::Generate(
|
||||
DWORD pChannelID,
|
||||
DWORD pAuthInfo,
|
||||
BOOL pUpgrade,
|
||||
DWORD serMin,
|
||||
DWORD serMax,
|
||||
char (&pKey)[25]
|
||||
) {
|
||||
BN_CTX *numContext = BN_CTX_new();
|
||||
@@ -231,6 +238,7 @@ void PIDGEN3::BINK2002::Generate(
|
||||
DWORD pData = pChannelID << 1 | pUpgrade;
|
||||
|
||||
BOOL noSquare;
|
||||
BOOL serialInRange;
|
||||
|
||||
do {
|
||||
EC_POINT *r = EC_POINT_new(eCurve);
|
||||
@@ -265,8 +273,16 @@ void PIDGEN3::BINK2002::Generate(
|
||||
// pHash = SHA1(79 || Channel ID || R.x || R.y)
|
||||
SHA1(msgBuffer, SHA_MSG_LENGTH_2003, msgDigest);
|
||||
|
||||
// Derive serial value from byte digest and do bounds checks.
|
||||
// This is important in some cases since serial can technically exceed 999999, affecting the derived Channel ID.
|
||||
|
||||
DWORD serial = (((BYDWORD(msgDigest + 4) >> 13) << 1) | (BYDWORD(msgDigest) >> 31)) & BITMASK(20);
|
||||
serialInRange = (serial >= serMin) && (serial <= serMax);
|
||||
if (!serialInRange) continue;
|
||||
|
||||
// Translate the byte digest into a 32-bit integer - this is our computed hash.
|
||||
// Truncate the hash to 31 bits.
|
||||
|
||||
DWORD pHash = BYDWORD(msgDigest) & BITMASK(31);
|
||||
|
||||
// Assemble the second SHA message.
|
||||
@@ -365,10 +381,11 @@ void PIDGEN3::BINK2002::Generate(
|
||||
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, " Serial: {:06d}\n", serial);
|
||||
fmt::print(UMSKT::debug, "\n");
|
||||
|
||||
EC_POINT_free(r);
|
||||
} while (pSignature > BITMASK(62) || noSquare);
|
||||
} while (pSignature > BITMASK(62) || noSquare || !serialInRange);
|
||||
// ↑ ↑ ↑
|
||||
// The signature can't be longer than 62 bits, else it will
|
||||
// overlap with the AuthInfo segment next to it.
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
EC_GROUP *eCurve,
|
||||
EC_POINT *basePoint,
|
||||
EC_POINT *publicKey,
|
||||
DWORD *pSerial,
|
||||
char (&cdKey)[25]
|
||||
);
|
||||
|
||||
@@ -60,6 +61,8 @@ public:
|
||||
DWORD pChannelID,
|
||||
DWORD pAuthInfo,
|
||||
BOOL pUpgrade,
|
||||
DWORD serMin,
|
||||
DWORD serMax,
|
||||
char (&pKey)[25]
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user