aboutsummaryrefslogtreecommitdiff
path: root/src/Protocols/GameSpy0/algorithm.cpp
diff options
context:
space:
mode:
authorDark1-dev <shansarkar272@gmail.com>2023-03-01 21:30:57 +0600
committerGitHub <noreply@github.com>2023-03-01 21:30:57 +0600
commit60a301a93b6057bb2c54ac04a7c38c38389037b3 (patch)
treeb09c5f8bc0045828c660654d8ed6744663856202 /src/Protocols/GameSpy0/algorithm.cpp
parentc784240d1af68dbd8d0466822b34fd05d6ccdda1 (diff)
downloadMasterserver-Qt5-60a301a93b6057bb2c54ac04a7c38c38389037b3.tar.gz
Masterserver-Qt5-60a301a93b6057bb2c54ac04a7c38c38389037b3.zip
Add files via upload
Diffstat (limited to 'src/Protocols/GameSpy0/algorithm.cpp')
-rw-r--r--src/Protocols/GameSpy0/algorithm.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/Protocols/GameSpy0/algorithm.cpp b/src/Protocols/GameSpy0/algorithm.cpp
new file mode 100644
index 0000000..5250079
--- /dev/null
+++ b/src/Protocols/GameSpy0/algorithm.cpp
@@ -0,0 +1,96 @@
+#include "securevalidate.h"
+
+/* This algorithm is based on Luigi Auriemma's gsmsalg 0.3.3,
+ * https://aluigi.altervista.org/papers/gsmsalg.h
+ * under GNU General Public License v2.
+ */
+QString generateValidateString(const QByteArray &cipher,
+ const QByteArray &secure,
+ const int &enctype)
+{
+ unsigned char cipherLength = static_cast<unsigned char>( cipher.length() );
+ unsigned char secureLength = static_cast<unsigned char>( secure.length() );
+
+ // fill array with ascii characters
+ unsigned char enc[256];
+ for (unsigned short j = 0; j < 256; j++)
+ {
+ enc[j] = static_cast<unsigned char>(j);
+ }
+
+ // cipher shuffle
+ unsigned char a = 0, x;
+ for (unsigned short j = 0; j < 256; j++)
+ {
+ a += enc[j] + cipher[j % cipherLength];
+ x = enc[a];
+ enc[a] = enc[j];
+ enc[j] = x;
+ }
+
+ // secure shuffle
+ unsigned char tmp[66];
+ unsigned char i = 0,
+ y = 0,
+ b = 0;
+ a = 0; // reset a
+ for (i = 0; i < cipherLength; i++)
+ {
+ a += secure.at(i) + 1;
+ x = enc[a];
+ b += x;
+ y = enc[b];
+ enc[b] = x;
+ enc[a] = y;
+ tmp[i] = static_cast<unsigned char>( secure.at(i) ^ enc[ (x+y) & 0xff ] );
+ }
+
+ // part of the enctype 1-2 process (uses i from previous loop)
+ for (secureLength = i; secureLength % 3; secureLength++)
+ {
+ tmp[secureLength] = 0;
+ }
+
+ // enctype 1 shuffle
+ if (enctype == 1)
+ {
+ for (i = 0; i < secureLength; i++)
+ {
+ tmp[i] = enctype1_data[ tmp[i] ];
+ }
+ }
+ else if (enctype == 2 )
+ {
+ for (i = 0; i < secureLength; i++)
+ {
+ tmp[i] = static_cast<unsigned char>(tmp[i] ^ cipher[i % cipherLength] );
+ }
+ }
+
+ // final shuffle and stitch validate response together
+ unsigned char z = 0;
+ QString validate;
+ for (i = 0; i < secureLength; i += 3)
+ {
+ x = (tmp[i]);
+ y = (tmp[i+1]);
+ z = (tmp[i+2]);
+
+ validate.append( charshift (x >> 2) );
+ validate.append( charshift (static_cast<unsigned char>(((x & 3) << 4) | (y >> 4)) ));
+ validate.append( charshift (static_cast<unsigned char>(((y & 15) << 2) | (z >> 6)) ));
+ validate.append( charshift (z & 63));
+ }
+ return validate;
+}
+
+// part of gsmsalg 0.3.3 and license
+unsigned char charshift ( const unsigned char &reg )
+{
+ if (reg < 26) return (reg + 'A');
+ if (reg < 52) return (reg + 'G');
+ if (reg < 62) return (reg - 4);
+ if (reg == 62) return ('+');
+ if (reg == 63) return ('/');
+ return (0);
+}