diff options
author | Shauren <shauren.trinity@gmail.com> | 2017-12-29 12:50:12 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2017-12-29 12:50:12 +0100 |
commit | b49fa9658a436c31ffc40100d5a55bee5a3f861e (patch) | |
tree | 38e79bad5feff33da73f3901e957bcbf91bc8060 /src | |
parent | 02022d3cd65f072874e9f5de061e0b158b6eb634 (diff) |
Tools/Patcher: Properly sign certificate bundle7.2.5/24742
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Cryptography/RSA.cpp | 17 | ||||
-rw-r--r-- | src/common/Cryptography/RSA.h | 18 | ||||
-rw-r--r-- | src/server/game/Server/Packets/AuthenticationPackets.cpp | 55 | ||||
-rw-r--r-- | src/tools/connection_patcher/Helper.cpp | 15 | ||||
-rw-r--r-- | src/tools/connection_patcher/Helper.hpp | 1 | ||||
-rw-r--r-- | src/tools/connection_patcher/Patches/Common.hpp | 36 | ||||
-rw-r--r-- | src/tools/connection_patcher/Patches/Mac.hpp | 15 | ||||
-rw-r--r-- | src/tools/connection_patcher/Patches/Windows.hpp | 16 | ||||
-rw-r--r-- | src/tools/connection_patcher/Patterns/Common.hpp | 5 | ||||
-rw-r--r-- | src/tools/connection_patcher/Patterns/Mac.hpp | 13 | ||||
-rw-r--r-- | src/tools/connection_patcher/Patterns/Windows.hpp | 16 | ||||
-rw-r--r-- | src/tools/connection_patcher/Program.cpp | 71 |
12 files changed, 155 insertions, 123 deletions
diff --git a/src/common/Cryptography/RSA.cpp b/src/common/Cryptography/RSA.cpp index 11bbbe1dac5..96199d34bb0 100644 --- a/src/common/Cryptography/RSA.cpp +++ b/src/common/Cryptography/RSA.cpp @@ -16,6 +16,8 @@ */ #include "RSA.h" +#include "BigNumber.h" +#include <openssl/bn.h> #include <openssl/pem.h> #include <algorithm> #include <iterator> @@ -88,6 +90,13 @@ bool Trinity::Crypto::RSA::LoadFromString(std::string const& keyPem, KeyTag) return true; } +BigNumber Trinity::Crypto::RSA::GetModulus() const +{ + BigNumber bn; + BN_copy(bn.BN(), _rsa->n); + return bn; +} + template <typename KeyTag> bool Trinity::Crypto::RSA::Encrypt(uint8 const* data, std::size_t dataLength, uint8* output, int32 paddingType) { @@ -97,6 +106,14 @@ bool Trinity::Crypto::RSA::Encrypt(uint8 const* data, std::size_t dataLength, ui return result != -1; } +bool Trinity::Crypto::RSA::Sign(int32 hashType, uint8 const* dataHash, std::size_t dataHashLength, uint8* output) +{ + uint32 signatureLength = 0; + int result = RSA_sign(hashType, dataHash, dataHashLength, output, &signatureLength, _rsa); + std::reverse(output, output + GetOutputSize()); + return result != -1; +} + namespace Trinity { namespace Crypto diff --git a/src/common/Cryptography/RSA.h b/src/common/Cryptography/RSA.h index 42849c03e4d..c0066ccbcfa 100644 --- a/src/common/Cryptography/RSA.h +++ b/src/common/Cryptography/RSA.h @@ -16,10 +16,13 @@ */ #include "Define.h" +#include <openssl/objects.h> #include <openssl/rsa.h> #include <string> #include <type_traits> +class BigNumber; + namespace Trinity { namespace Crypto @@ -27,11 +30,13 @@ namespace Crypto class TC_COMMON_API RSA { public: + struct PublicKey {}; + struct PrivateKey {}; + struct NoPadding : std::integral_constant<int32, RSA_NO_PADDING> {}; struct PKCS1Padding : std::integral_constant<int32, RSA_PKCS1_PADDING> {}; - struct PrivateKey {}; - struct PublicKey {}; + struct SHA256 : std::integral_constant<int32, NID_sha256> {}; RSA(); RSA(RSA&& rsa); @@ -44,6 +49,7 @@ public: bool LoadFromString(std::string const& keyPem, KeyTag); uint32 GetOutputSize() const { return uint32(RSA_size(_rsa)); } + BigNumber GetModulus() const; template <typename KeyTag, typename PaddingTag> bool Encrypt(uint8 const* data, std::size_t dataLength, uint8* output, KeyTag, PaddingTag) @@ -51,10 +57,18 @@ public: return Encrypt<KeyTag>(data, dataLength, output, PaddingTag::value); } + template <typename HashTag> + bool Sign(uint8 const* dataHash, std::size_t dataHashLength, uint8* output, HashTag) + { + return Sign(HashTag::value, dataHash, dataHashLength, output); + } + private: template <typename KeyTag> bool Encrypt(uint8 const* data, std::size_t dataLength, uint8* output, int32 paddingType); + bool Sign(int32 hashType, uint8 const* dataHash, std::size_t dataHashLength, uint8* output); + RSA(RSA const& rsa) = delete; RSA& operator=(RSA const& rsa) = delete; diff --git a/src/server/game/Server/Packets/AuthenticationPackets.cpp b/src/server/game/Server/Packets/AuthenticationPackets.cpp index cf634359f66..9ed7d889d70 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.cpp +++ b/src/server/game/Server/Packets/AuthenticationPackets.cpp @@ -226,33 +226,34 @@ uint8 const WorldPackets::Auth::ConnectTo::PiDigits[130] = namespace { -std::string RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\n" -"MIIEpAIBAAKCAQEA7rPc1NPDtFRRzmZbyzK48PeSU8YZ8gyFL4omqXpFn2DE683q\n" -"f41Z2FeyYHsJTJtouMft7x6ADeZrN1tTkOsYEw1/Q2SD2pjmrMIwooKlxsvH+4af\n" -"n6kCagNJxTj7wMhVzMDOJZG+hc/R0TfOzIPS6jCAB3uAn51EVCIpvoba20jFqfkT\n" -"NpUjdvEO3IQNlAISqJfzOxTuqm+YBSdOH6Ngpana2BffM8viE1SLGLDKubuIZAbf\n" -"dabXYQC7sFoOetR3CE0V4hCDsASqnot3qQaJXQhdD7gua8HLZM9uXNtPWGUIUfsN\n" -"SBpvtj0fC93+Gx3wv7Ana/WOvMdAAf+nC4DWXwIDAQABAoIBACKa5q/gB2Y0Nyvi\n" -"APrDXrZoXclRVd+WWxSaRaKaPE+vuryovI9DUbwgcpa0H5QAj70CFwdsd4oMVozO\n" -"6519x56zfTiq8MaXFhIDkQNuR1Q7pMFdMfT2jogJ8/7olO7M3EtzxC8EIwfJKhTX\n" -"r15M2h3jbBwplmsNZKOB1GVvrXjOm1KtOZ4CTTM0WrPaLVDT9ax8pykjmFw16vGP\n" -"j/R5Dky9VpabtfZOu/AEW259XDEiQgTrB4Eg+S4GJjHqAzPZBmMy/xhlDK4oMXef\n" -"qXScfD4w0RxuuCFr6lxLPZz0S35BK1kIWmIkuv+9eQuI4Hr1CyVwch4fkfvrp84x\n" -"8tvAFnkCgYEA87NZaG9a8/Mob6GgY4BVLHJVOSzzFdNyMA+4LfSbtzgON2RSZyeD\n" -"0JpDowwXssw5XOyUUctj2cLLdlMCpDfdzk4F/PEakloDJWpason3lmur0/5Oq3T9\n" -"3+fnNUl4d3UOs1jcJ1yGQ/BfrTyRTcEoZx8Mu9mJ4ituVkKuLeG5vX0CgYEA+r/w\n" -"QBJS6kDyQPj1k/SMClUhWhyADwDod03hHTQHc9BleJyjXmVy+/pWhN7aELhjgLbf\n" -"o/Gm3aKJjCxS4qBmqUKwAvGoSVux1Bo2ZjcfF7sX9BXBOlFTG+bPVCZUoaksTyXN\n" -"g7GsA1frKkWWkgQuOeK3o/p9IZoBl93vEgcTGgsCgYEAv5ucCIjFMllUybCCsrkM\n" -"Ps4GQ9YbqmV9ulwhq8BPTlc8lkDCqWhgM3uXAnNXjrUTxQQd+dG4yFZoMrhBs2xZ\n" -"cQPXoXDQO5GaN6jPduETUamGiD/DCvwJQCrNlxAVL5dR36FWN3x/9JriHwsoE8Jz\n" -"SeEX2frIdpM/RYNX/6sipuECgYEA+rwFRDxOdvm8hGWuQ2WMxyQ7Nn07PEV/LxVM\n" -"HkSRkyh23vVakyDEqty3uSOSUJfgv6ud07TnU8ac3fLQatdT8LrDgB4fVkN/fYU8\n" -"kldaGwO1vxgl4OfDQCo7dXzisciViwtVBvQZ+jnm6J0vJBFUHAPt9+WZTIlQQIjm\n" -"71LtseMCgYBSAhs6lshtz+ujR3fmc4QqJVGqeXvEBPAVm6yYoKYRLwVs/rFv3WLN\n" -"LOwwBQ6lz7P9RqYYB5wVlaRvEhb9+lCve/xVcxMeZ5GkOBPxVygYV9l/wNdE25Nz\n" -"OHYtKG3GK3GEcFDwZU2LPHq21EroUAdtRfbrJ4KW2yc8igtXKxTBYw==\n" -"-----END RSA PRIVATE KEY-----\n"; +std::string RSAPrivateKey = R"(-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA7rPc1NPDtFRRzmZbyzK48PeSU8YZ8gyFL4omqXpFn2DE683q +f41Z2FeyYHsJTJtouMft7x6ADeZrN1tTkOsYEw1/Q2SD2pjmrMIwooKlxsvH+4af +n6kCagNJxTj7wMhVzMDOJZG+hc/R0TfOzIPS6jCAB3uAn51EVCIpvoba20jFqfkT +NpUjdvEO3IQNlAISqJfzOxTuqm+YBSdOH6Ngpana2BffM8viE1SLGLDKubuIZAbf +dabXYQC7sFoOetR3CE0V4hCDsASqnot3qQaJXQhdD7gua8HLZM9uXNtPWGUIUfsN +SBpvtj0fC93+Gx3wv7Ana/WOvMdAAf+nC4DWXwIDAQABAoIBACKa5q/gB2Y0Nyvi +APrDXrZoXclRVd+WWxSaRaKaPE+vuryovI9DUbwgcpa0H5QAj70CFwdsd4oMVozO +6519x56zfTiq8MaXFhIDkQNuR1Q7pMFdMfT2jogJ8/7olO7M3EtzxC8EIwfJKhTX +r15M2h3jbBwplmsNZKOB1GVvrXjOm1KtOZ4CTTM0WrPaLVDT9ax8pykjmFw16vGP +j/R5Dky9VpabtfZOu/AEW259XDEiQgTrB4Eg+S4GJjHqAzPZBmMy/xhlDK4oMXef +qXScfD4w0RxuuCFr6lxLPZz0S35BK1kIWmIkuv+9eQuI4Hr1CyVwch4fkfvrp84x +8tvAFnkCgYEA87NZaG9a8/Mob6GgY4BVLHJVOSzzFdNyMA+4LfSbtzgON2RSZyeD +0JpDowwXssw5XOyUUctj2cLLdlMCpDfdzk4F/PEakloDJWpason3lmur0/5Oq3T9 +3+fnNUl4d3UOs1jcJ1yGQ/BfrTyRTcEoZx8Mu9mJ4ituVkKuLeG5vX0CgYEA+r/w +QBJS6kDyQPj1k/SMClUhWhyADwDod03hHTQHc9BleJyjXmVy+/pWhN7aELhjgLbf +o/Gm3aKJjCxS4qBmqUKwAvGoSVux1Bo2ZjcfF7sX9BXBOlFTG+bPVCZUoaksTyXN +g7GsA1frKkWWkgQuOeK3o/p9IZoBl93vEgcTGgsCgYEAv5ucCIjFMllUybCCsrkM +Ps4GQ9YbqmV9ulwhq8BPTlc8lkDCqWhgM3uXAnNXjrUTxQQd+dG4yFZoMrhBs2xZ +cQPXoXDQO5GaN6jPduETUamGiD/DCvwJQCrNlxAVL5dR36FWN3x/9JriHwsoE8Jz +SeEX2frIdpM/RYNX/6sipuECgYEA+rwFRDxOdvm8hGWuQ2WMxyQ7Nn07PEV/LxVM +HkSRkyh23vVakyDEqty3uSOSUJfgv6ud07TnU8ac3fLQatdT8LrDgB4fVkN/fYU8 +kldaGwO1vxgl4OfDQCo7dXzisciViwtVBvQZ+jnm6J0vJBFUHAPt9+WZTIlQQIjm +71LtseMCgYBSAhs6lshtz+ujR3fmc4QqJVGqeXvEBPAVm6yYoKYRLwVs/rFv3WLN +LOwwBQ6lz7P9RqYYB5wVlaRvEhb9+lCve/xVcxMeZ5GkOBPxVygYV9l/wNdE25Nz +OHYtKG3GK3GEcFDwZU2LPHq21EroUAdtRfbrJ4KW2yc8igtXKxTBYw== +-----END RSA PRIVATE KEY----- +)"; std::unique_ptr<Trinity::Crypto::RSA> ConnectToRSA; diff --git a/src/tools/connection_patcher/Helper.cpp b/src/tools/connection_patcher/Helper.cpp index 50ad301132d..3dc1b10b9cf 100644 --- a/src/tools/connection_patcher/Helper.cpp +++ b/src/tools/connection_patcher/Helper.cpp @@ -126,15 +126,6 @@ namespace Connection_Patcher return Constants::BinaryTypes(*reinterpret_cast<uint32_t const*>(data.data())); } - std::string GetFileChecksum(std::vector<unsigned char> const& data) - { - SHA256Hash h; - h.UpdateData(data.data(), data.size()); - h.Finalize(); - - return ByteArrayToHexStr(h.GetDigest(), h.GetLength()); - } - std::set<size_t> SearchOffset(std::vector<unsigned char> const& binary, std::vector<unsigned char> const& pattern) { std::set<size_t> offsets; @@ -144,12 +135,6 @@ namespace Connection_Patcher for (size_t j = 0; j < pattern.size(); j++) { - if (pattern[j] == 0) - { - matches++; - continue; - } - if (binary[i + j] != pattern[j]) break; diff --git a/src/tools/connection_patcher/Helper.hpp b/src/tools/connection_patcher/Helper.hpp index 1771d431d61..bd7652c8101 100644 --- a/src/tools/connection_patcher/Helper.hpp +++ b/src/tools/connection_patcher/Helper.hpp @@ -38,7 +38,6 @@ namespace Connection_Patcher void CopyDir(boost::filesystem::path const & source, boost::filesystem::path const & destination); void DownloadFile(const std::string& serverName, int port, const std::string& getCommand, std::ostream& out); Constants::BinaryTypes GetBinaryType(std::vector<unsigned char> const& data); - std::string GetFileChecksum(std::vector<unsigned char> const& data); std::set<size_t> SearchOffset(std::vector<unsigned char> const& binary, std::vector<unsigned char> const& pattern); uint32_t GetBuildNumber(std::vector<unsigned char> const& binary); } diff --git a/src/tools/connection_patcher/Patches/Common.hpp b/src/tools/connection_patcher/Patches/Common.hpp index 3a8bb50eb84..4b82a955472 100644 --- a/src/tools/connection_patcher/Patches/Common.hpp +++ b/src/tools/connection_patcher/Patches/Common.hpp @@ -51,7 +51,7 @@ namespace Connection_Patcher }; } static std::string VersionsFile() { return "trinity6.github.io/%s/%s/build/versi"; }; - static std::vector<unsigned char> CertFileName() { return{ 't', 'c', '_', 'b', 'u', 'n', 'd', 'l', 'e', '.', 't', 'x', 't', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; } + static std::vector<unsigned char> CertBundleUrl() { return { 'h', 't', 't', 'p', 's', ':', '/', '/', 't', 'r', 'i', 'n', 'i', 't', 'y', '6', '.', 'g', 'i', 't', 'h', 'u', 'b', '.', 'i', 'o', '/', 'B', 'n', 'e', 't', '/', 'z', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '/', 'c', 'l', 'i', 'e', 'n', 't', '/', 'b', 'g', 's', '-', 'k', 'e', 'y', '-', 'f', 'i', 'n', 'g', 'e', 'r', 'p', 'r', 'i', 'n', 't' }; } static std::string CertificateBundle() { return @@ -66,7 +66,39 @@ R"({ "SigningCertificates": [ { "RawData": "-----BEGIN CERTIFICATE-----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-----END CERTIFICATE-----" } ] -}NGISerting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature)"; +})"; + } + static std::string CertificatePrivateKey() + { + return +R"(-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAwN3EYmKhDGawGrh62wAgjh3wr4CcV6lp61Ev39jzTkgetXDB +F2SWC9s/pzS/h10HQwL9P0cYlqbZHj/darOphcqplK05WsJC876lUASSeVWVPiHs +mfpSzjx65qV2PfmcNE1SUEizOOfpaoxvLfVqh5y4MkuSxXxOXCXS9CnQBwQo8f/4 +uV6czHZgigi7CSID75VK3VhqvlTaLYFoEiOpjWNAQ7x/18sv+VoSVuX+alYez2PD +wU+hl0CpzEIqtaavntce9sQ3uEd3eXYGAJp6X+bOVItRmUhb3WXoIXmHMaLe5oSc +cINa17ZL7H2ISOqr/1Pfq84Ck/VStbzEfJdTZwIDAQABAoIBAHcu1DQERQd30a3B +gNIi4vtPzzN1I6gcXgL3+cC3vasLcEapdflxxDNxeoVmWFFbEKi9iSf4VF6MnrFN +wBM3ETRHh8IDxeSrFVqw3lFzcdyfIYnyxtZkVZVy1HQBne8wd/HuMkbAllg9IAYi +4HWjKgDBvSX/g6Sca4QQL6uIxy/9s3Z4K2vU8KbvUpwo+ON4HMt61fgrIrbEUVCl +TMCVEf8UphwHctmQJb/Pr0+BCTdiv04ga1dkt+ZyR2o0VN6T/zKDqk4m1sSl0GZz +8sn63GbuTlwHcm9GgkaxoeeZJK1/sdOSIZN8W3PpnyHrAZJlNOY7G684F1mBaWV1 +PGCcVtkCgYEA8jCDTGub7ZyMk48x+8L3Devja3TQz7YNIGkVEbQBpNw4gDV8j1m6 +EgqFdzowkY+gbA76ylNfm6Aa66RDR/LbTbXlsNd8YkXcbU3xDQ96F6cS51VBkled +hq+iAuGJB9VYN5yP1P/Oswg/AFMjOnsfBL/1zFo26364z9x8zazw0wsCgYEAy907 +mpkk59AQ4YIDSR9wK2YpXv6HoBPFld6m7PAnBWFO0uNtQ0YppbYbrhmDqrxUoFud +ZiEHIa0gLlp9lHr+UdUAMPDlJ6gbMnJW3U5qiVuuZA13tiZFlv11qUeU1tQUzTUv +ZoIISN15Im0PQzUFbTxSFbS+vTYjsedv1C9UOpUCgYEAkTaTUzvmV3cZNtSSFLFW +ros0Zda56QDwJ/G5x06V+cJtQjpPwCf9kBms4ssKGgzzFDd7GdsZpVc/LPDlwnsU +ESkyWnEpzEa1HvivwrP38bykcf5Ffbh45CvkyTNvlTnPVjDScNUcm24jUE+I/OSb +uZ5bg7bH3TWzHDbIwg2iq/cCgYB+DPqvqoVhOAtYBBWX/vJSQ0bNT7/4QIFpG1RH +KG5YK0SbrLeAYz+ZELKowWniBbSluj/mSAGq1usQ/i6rwijB3FvT5v8puA2o8X24 +NKY27BM2FgWxAJUCuREpa/Mhqdx6zanTTg9lTlt558kKGxyR4Dw445sUTwdfFuTU +Y7dGyQKBgAG0vyOdfku9TlPX2a3LasM5jkbxljeTlCJUlahW7LSoQEmLoEhOM4Ja +6CA5PADhA16pOUweKjOtSkNEcVEorFNjlH34PpnsysF+NsDBP5HEy0eYyHSYwg1Y +7BGwQxUOoBaUKMu7jVQcffrKiWOGEXzBDSEZ3A30t7+JIS7qy1d1 +-----END RSA PRIVATE KEY----- +)"; } }; } diff --git a/src/tools/connection_patcher/Patches/Mac.hpp b/src/tools/connection_patcher/Patches/Mac.hpp index 16fadd51f47..49f3e175fdc 100644 --- a/src/tools/connection_patcher/Patches/Mac.hpp +++ b/src/tools/connection_patcher/Patches/Mac.hpp @@ -25,18 +25,13 @@ namespace Connection_Patcher { namespace Patches { - namespace Mac + struct Mac { - struct x64 + static std::vector<unsigned char> LauncherLoginParametersLocation() { - static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x48, 0x8D, 0x55, 0xDC, 0x31, 0xDB, 0xB1, 0x01 }; } - static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0x45, 0x84, 0xFF, 0xB0, 0x01, 0xEB, 0x03, 0x44, 0x89 }; } - static std::vector<unsigned char> LauncherLoginParametersLocation() - { - char const path[] = "org.trnity"; // not a typo, length must match original - return std::vector<unsigned char>(std::begin(path), std::end(path)); - } - }; + char const path[] = "org.trnity"; // not a typo, length must match original + return std::vector<unsigned char>(std::begin(path), std::end(path)); + } }; } } diff --git a/src/tools/connection_patcher/Patches/Windows.hpp b/src/tools/connection_patcher/Patches/Windows.hpp index 1e873e5521c..ce1f705fd19 100644 --- a/src/tools/connection_patcher/Patches/Windows.hpp +++ b/src/tools/connection_patcher/Patches/Windows.hpp @@ -25,27 +25,13 @@ namespace Connection_Patcher { namespace Patches { - namespace Windows + struct Windows { static std::vector<unsigned char> LauncherLoginParametersLocation() { char const path[] = R"(Software\TrinityCore Developers\Battle.net\Launch Options\)"; return std::vector<unsigned char>(std::begin(path), std::end(path)); } - - struct x86 - { - static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x6A, 0x01 }; } - static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0x59, 0x59, 0x84, 0xC0, 0xEB }; } - static std::vector<unsigned char> LauncherLoginParametersLocation() { return ::Connection_Patcher::Patches::Windows::LauncherLoginParametersLocation(); } - }; - - struct x64 - { - static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x41, 0xB1, 0x01 }; } - static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0xEB }; } - static std::vector<unsigned char> LauncherLoginParametersLocation() { return ::Connection_Patcher::Patches::Windows::LauncherLoginParametersLocation(); } - }; }; } } diff --git a/src/tools/connection_patcher/Patterns/Common.hpp b/src/tools/connection_patcher/Patterns/Common.hpp index c46a8f9fc5f..9fd80332379 100644 --- a/src/tools/connection_patcher/Patterns/Common.hpp +++ b/src/tools/connection_patcher/Patterns/Common.hpp @@ -29,9 +29,10 @@ namespace Connection_Patcher { static std::vector<unsigned char> Portal() { return { '.', 'a', 'c', 't', 'u', 'a' , 'l', '.', 'b', 'a', 't', 't', 'l', 'e', '.', 'n', 'e', 't', 0x00 }; } static std::vector<unsigned char> Modulus() { return { 0x91, 0xD5, 0x9B, 0xB7, 0xD4, 0xE1, 0x83, 0xA5 }; } - static std::vector<unsigned char> BinaryVersion() { return{ 0x3C, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E }; } + static std::vector<unsigned char> BinaryVersion() { return { 0x3C, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E }; } static std::vector<unsigned char> VersionsFile() { return { '%', 's', '.', 'p', 'a', 't', 'c', 'h', '.', 'b', 'a', 't', 't', 'l', 'e', '.', 'n', 'e', 't', ':', '1', '1', '1', '9', '/', '%', 's', '/', 'v', 'e', 'r', 's', 'i', 'o', 'n', 's' }; } - static std::vector<unsigned char> CertFileName() { return { 'c', 'a', '_', 'b', 'u', 'n', 'd', 'l', 'e', '.', 't', 'x', 't', '.', 's', 'i', 'g', 'n', 'e', 'd', 0x00 }; } + static std::vector<unsigned char> CertBundleUrl() { return { 'h', 't', 't', 'p', ':', '/', '/', 'n', 'y', 'd', 'u', 's', '-', 'q', 'a', '.', 'w', 'e', 'b', '.', 'b', 'l', 'i', 'z', 'z', 'a', 'r', 'd', '.', 'n', 'e', 't', '/', 'B', 'n', 'e', 't', '/', 'z', 'x', 'x', '/', 'c', 'l', 'i', 'e', 'n', 't', '/', 'b', 'g', 's', '-', 'k', 'e', 'y', '-', 'f', 'i', 'n', 'g', 'e', 'r', 'p', 'r', 'i', 'n', 't' }; } + static std::vector<unsigned char> CertSignatureModulus() { return { 0x85, 0xF3, 0x7B, 0x14, 0x5A, 0x9C, 0x48, 0xF6 }; } }; } } diff --git a/src/tools/connection_patcher/Patterns/Mac.hpp b/src/tools/connection_patcher/Patterns/Mac.hpp index e2d2eaa74f7..bb44bc9d2e4 100644 --- a/src/tools/connection_patcher/Patterns/Mac.hpp +++ b/src/tools/connection_patcher/Patterns/Mac.hpp @@ -25,18 +25,9 @@ namespace Connection_Patcher { namespace Patterns { - namespace Mac + struct Mac { - struct x64 - { - static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x48, 0x8D, 0x55, 0xDC, 0x31, 0xDB, 0x31, 0xC9 }; } - static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0x45, 0x84, 0xFF, 0xB0, 0x01, 0x75, 0x03, 0x44, 0x89 }; } - static std::vector<unsigned char> LauncherLoginParametersLocation() - { - char const path[] = "net.battle"; - return std::vector<unsigned char>(std::begin(path), std::end(path)); - } - }; + static std::vector<unsigned char> LauncherLoginParametersLocation() { return { 'n','e','t','.','b','a','t','t','l','e',0 }; } }; } } diff --git a/src/tools/connection_patcher/Patterns/Windows.hpp b/src/tools/connection_patcher/Patterns/Windows.hpp index d97f92b2a88..450d82773b6 100644 --- a/src/tools/connection_patcher/Patterns/Windows.hpp +++ b/src/tools/connection_patcher/Patterns/Windows.hpp @@ -25,27 +25,13 @@ namespace Connection_Patcher { namespace Patterns { - namespace Windows + struct Windows { static std::vector<unsigned char> LauncherLoginParametersLocation() { char const path[] = R"(Software\Blizzard Entertainment\Battle.net\Launch Options\)"; return std::vector<unsigned char>(std::begin(path), std::end(path)); } - - struct x86 - { - static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x6A, 0x00, 0x50, 0x8D, 0x45, 0xF8, 0x50, 0x68 }; } - static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0x59, 0x59, 0x84, 0xC0, 0x75, 0x08, 0x46, 0x83, 0xFE, 0x02 }; } - static std::vector<unsigned char> LauncherLoginParametersLocation() { return ::Connection_Patcher::Patterns::Windows::LauncherLoginParametersLocation(); } - }; - - struct x64 - { - static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x45, 0x33, 0xC9, 0x48, 0x89, 0x9C, 0x24, 0x90, 0x02 }; } - static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0x75, 0x0B, 0x48, 0xFF, 0xC7, 0x48, 0x83, 0xFF, 0x02 }; } - static std::vector<unsigned char> LauncherLoginParametersLocation() { return ::Connection_Patcher::Patterns::Windows::LauncherLoginParametersLocation(); } - }; }; } } diff --git a/src/tools/connection_patcher/Program.cpp b/src/tools/connection_patcher/Program.cpp index 7f5342be22e..d327a1b0fdf 100644 --- a/src/tools/connection_patcher/Program.cpp +++ b/src/tools/connection_patcher/Program.cpp @@ -26,7 +26,9 @@ #include "Patterns/Windows.hpp" #include "Banner.h" -#include "CompilerDefs.h" +#include "BigNumber.h" +#include "RSA.h" +#include "SHA256.h" #include <boost/algorithm/string/replace.hpp> #include <boost/program_options.hpp> @@ -57,16 +59,14 @@ namespace Connection_Patcher patcher->Patch(Patches::Common::Modulus(), Patterns::Common::Modulus()); std::cout << "patching BNet certificate file location\n"; - // replace name of the file with certificates - patcher->Patch(Patches::Common::CertFileName(), Patterns::Common::CertFileName()); + // replace certificate bundle url + patcher->Patch(Patches::Common::CertBundleUrl(), Patterns::Common::CertBundleUrl()); - std::cout << "patching BNet certificate file to load from local path instead of CASC\n"; - // force loading tc_bundle.txt from local directory instead of CASC - patcher->Patch(PATCH::CertBundleCASCLocalFile(), PATTERN::CertBundleCASCLocalFile()); - - std::cout << "patching BNet certificate file signature check\n"; - // remove signature check from certificate bundle - patcher->Patch(PATCH::CertBundleSignatureCheck(), PATTERN::CertBundleSignatureCheck()); + std::cout << "patching BNet certificate file signature\n"; + Trinity::Crypto::RSA rsa; + rsa.LoadFromString(Patches::Common::CertificatePrivateKey(), Trinity::Crypto::RSA::PrivateKey{}); + std::unique_ptr<uint8[]> modulusArray = rsa.GetModulus().AsByteArray(256); + patcher->Patch(std::vector<uint8>(modulusArray.get(), modulusArray.get() + 256), Patterns::Common::CertSignatureModulus()); std::cout << "patching Versions\n"; // sever the connection to blizzard's versions file to stop it from updating and replace with custom version @@ -90,11 +90,27 @@ namespace Connection_Patcher void WriteCertificateBundle(boost::filesystem::path const& dest) { + if (!boost::filesystem::exists(dest.parent_path()) && + !boost::filesystem::create_directories(dest.parent_path())) + throw std::runtime_error("could not create " + dest.parent_path().string()); + std::ofstream ofs(dest.string(), std::ofstream::binary); if (!ofs) throw std::runtime_error("could not open " + dest.string()); - ofs << std::noskipws << Patches::Common::CertificateBundle(); + ofs << std::noskipws << Patches::Common::CertificateBundle() << "NGIS"; + + SHA256Hash signatureHash; + signatureHash.UpdateData(Patches::Common::CertificateBundle()); + signatureHash.UpdateData("Blizzard Certificate Bundle"); + signatureHash.Finalize(); + std::array<uint8, 256> signature; + + Trinity::Crypto::RSA rsa; + rsa.LoadFromString(Patches::Common::CertificatePrivateKey(), Trinity::Crypto::RSA::PrivateKey{}); + rsa.Sign(signatureHash.GetDigest(), signatureHash.GetLength(), signature.data(), Trinity::Crypto::RSA::SHA256{}); + + ofs.write(reinterpret_cast<char const*>(signature.data()), signature.size()); } } @@ -149,7 +165,23 @@ int main(int argc, char** argv) std::string const binary_path(std::move(vm["path"].as<std::string>())); std::string renamed_binary_path(binary_path); + std::wstring appDataPath; +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS + wchar_t* tempPath(nullptr); + SHGetKnownFolderPath(FOLDERID_ProgramData, 0, NULL, &tempPath); + appDataPath = std::wstring(tempPath); + CoTaskMemFree(tempPath); +#elif TRINITY_PLATFORM == TRINITY_PLATFORM_UNIX + char* tempPath(nullptr); + if ((tempPath = getenv("HOME")) == nullptr) + tempPath = getpwuid(getuid())->pw_dir; + std::string tempPathStr(tempPath); + appDataPath.assign(tempPathStr.begin(), tempPathStr.end()); + appDataPath += std::wstring(L"/.wine/drive_c/users/Public/Application Data"); +#elif TRINITY_PLATFORM == TRINITY_PLATFORM_APPLE + appDataPath = L"/Users/Shared"; +#endif std::cout << "Creating patched binary..." << std::endl; Patcher patcher(binary_path); @@ -166,20 +198,13 @@ int main(int argc, char** argv) switch (patcher.GetType()) { case Constants::BinaryTypes::Pe32: - std::cout << "Win32 client...\n"; - - boost::algorithm::replace_all(renamed_binary_path, ".exe", "_Patched.exe"); - do_patches<Patches::Windows::x86, Patterns::Windows::x86> - (&patcher, renamed_binary_path, wowBuild); - WriteCertificateBundle(boost::filesystem::path(binary_path).remove_filename() / "tc_bundle.txt"); - break; case Constants::BinaryTypes::Pe64: - std::cout << "Win64 client...\n"; + std::cout << (patcher.GetType() == Constants::BinaryTypes::Pe64 ? "Win64" : "Win32") << " client...\n"; boost::algorithm::replace_all(renamed_binary_path, ".exe", "_Patched.exe"); - do_patches<Patches::Windows::x64, Patterns::Windows::x64> + do_patches<Patches::Windows, Patterns::Windows> (&patcher, renamed_binary_path, wowBuild); - WriteCertificateBundle(boost::filesystem::path(binary_path).remove_filename() / "tc_bundle.txt"); + WriteCertificateBundle(boost::filesystem::path(appDataPath) / L"Blizzard Entertainment/Battle.net/Cache/web_cert_bundle"); break; case Constants::BinaryTypes::Mach64: std::cout << "Mac client...\n"; @@ -189,14 +214,14 @@ int main(int argc, char** argv) , boost::filesystem::path(renamed_binary_path).parent_path()/*MacOS*/.parent_path()/*Contents*/.parent_path() ); - do_patches<Patches::Mac::x64, Patterns::Mac::x64> + do_patches<Patches::Mac, Patterns::Mac> (&patcher, renamed_binary_path, wowBuild); { namespace fs = boost::filesystem; fs::permissions(renamed_binary_path, fs::add_perms | fs::others_exe | fs::group_exe | fs::owner_exe); } - WriteCertificateBundle(boost::filesystem::path(binary_path).parent_path()/*MacOS*/.parent_path()/*Contents*/.parent_path()/*World of Warcraft.app*/.parent_path() / "tc_bundle.txt"); + WriteCertificateBundle(boost::filesystem::path(appDataPath) / "Blizzard/Battle.net/Cache/web_cert_bundle"); break; default: throw std::runtime_error("Type: " + std::to_string(static_cast<uint32_t>(patcher.GetType())) + " not supported!"); |