aboutsummaryrefslogtreecommitdiff
path: root/src/common/Cryptography
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/Cryptography')
-rw-r--r--src/common/Cryptography/ARC4.cpp51
-rw-r--r--src/common/Cryptography/ARC4.h37
-rw-r--r--src/common/Cryptography/Authentication/AuthCrypt.cpp75
-rw-r--r--src/common/Cryptography/Authentication/AuthCrypt.h42
-rw-r--r--src/common/Cryptography/BigNumber.cpp201
-rw-r--r--src/common/Cryptography/BigNumber.h100
-rw-r--r--src/common/Cryptography/HMACSHA1.cpp57
-rw-r--r--src/common/Cryptography/HMACSHA1.h47
-rw-r--r--src/common/Cryptography/OpenSSLCrypto.cpp59
-rw-r--r--src/common/Cryptography/OpenSSLCrypto.h33
-rw-r--r--src/common/Cryptography/SHA1.cpp69
-rw-r--r--src/common/Cryptography/SHA1.h50
-rw-r--r--src/common/Cryptography/WardenKeyGeneration.h81
13 files changed, 902 insertions, 0 deletions
diff --git a/src/common/Cryptography/ARC4.cpp b/src/common/Cryptography/ARC4.cpp
new file mode 100644
index 00000000000..d1082b39347
--- /dev/null
+++ b/src/common/Cryptography/ARC4.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ARC4.h"
+
+ARC4::ARC4(uint8 len) : m_ctx()
+{
+ EVP_CIPHER_CTX_init(&m_ctx);
+ EVP_EncryptInit_ex(&m_ctx, EVP_rc4(), NULL, NULL, NULL);
+ EVP_CIPHER_CTX_set_key_length(&m_ctx, len);
+}
+
+ARC4::ARC4(uint8 *seed, uint8 len) : m_ctx()
+{
+ EVP_CIPHER_CTX_init(&m_ctx);
+ EVP_EncryptInit_ex(&m_ctx, EVP_rc4(), NULL, NULL, NULL);
+ EVP_CIPHER_CTX_set_key_length(&m_ctx, len);
+ EVP_EncryptInit_ex(&m_ctx, NULL, NULL, seed, NULL);
+}
+
+ARC4::~ARC4()
+{
+ EVP_CIPHER_CTX_cleanup(&m_ctx);
+}
+
+void ARC4::Init(uint8 *seed)
+{
+ EVP_EncryptInit_ex(&m_ctx, NULL, NULL, seed, NULL);
+}
+
+void ARC4::UpdateData(int len, uint8 *data)
+{
+ int outlen = 0;
+ EVP_EncryptUpdate(&m_ctx, data, &outlen, data, len);
+ EVP_EncryptFinal_ex(&m_ctx, data, &outlen);
+}
diff --git a/src/common/Cryptography/ARC4.h b/src/common/Cryptography/ARC4.h
new file mode 100644
index 00000000000..16a0cb92eb9
--- /dev/null
+++ b/src/common/Cryptography/ARC4.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _AUTH_SARC4_H
+#define _AUTH_SARC4_H
+
+#include <openssl/evp.h>
+#include "Define.h"
+
+class ARC4
+{
+ public:
+ ARC4(uint8 len);
+ ARC4(uint8 *seed, uint8 len);
+ ~ARC4();
+ void Init(uint8 *seed);
+ void UpdateData(int len, uint8 *data);
+ private:
+ EVP_CIPHER_CTX m_ctx;
+};
+
+#endif
diff --git a/src/common/Cryptography/Authentication/AuthCrypt.cpp b/src/common/Cryptography/Authentication/AuthCrypt.cpp
new file mode 100644
index 00000000000..153726e6950
--- /dev/null
+++ b/src/common/Cryptography/Authentication/AuthCrypt.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "AuthCrypt.h"
+#include "Cryptography/HMACSHA1.h"
+#include "Cryptography/BigNumber.h"
+
+#include <cstring>
+
+AuthCrypt::AuthCrypt() :
+ _clientDecrypt(SHA_DIGEST_LENGTH), _serverEncrypt(SHA_DIGEST_LENGTH),
+ _initialized(false)
+{ }
+
+void AuthCrypt::Init(BigNumber* K)
+{
+ uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 };
+ HmacHash serverEncryptHmac(SEED_KEY_SIZE, (uint8*)ServerEncryptionKey);
+ uint8 *encryptHash = serverEncryptHmac.ComputeHash(K);
+
+ uint8 ServerDecryptionKey[SEED_KEY_SIZE] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE };
+ HmacHash clientDecryptHmac(SEED_KEY_SIZE, (uint8*)ServerDecryptionKey);
+ uint8 *decryptHash = clientDecryptHmac.ComputeHash(K);
+
+ //ARC4 _serverDecrypt(encryptHash);
+ _clientDecrypt.Init(decryptHash);
+ _serverEncrypt.Init(encryptHash);
+ //ARC4 _clientEncrypt(decryptHash);
+
+ // Drop first 1024 bytes, as WoW uses ARC4-drop1024.
+ uint8 syncBuf[1024];
+ memset(syncBuf, 0, 1024);
+
+ _serverEncrypt.UpdateData(1024, syncBuf);
+ //_clientEncrypt.UpdateData(1024, syncBuf);
+
+ memset(syncBuf, 0, 1024);
+
+ //_serverDecrypt.UpdateData(1024, syncBuf);
+ _clientDecrypt.UpdateData(1024, syncBuf);
+
+ _initialized = true;
+}
+
+void AuthCrypt::DecryptRecv(uint8 *data, size_t len)
+{
+ if (!_initialized)
+ return;
+
+ _clientDecrypt.UpdateData(len, data);
+}
+
+void AuthCrypt::EncryptSend(uint8 *data, size_t len)
+{
+ if (!_initialized)
+ return;
+
+ _serverEncrypt.UpdateData(len, data);
+}
+
diff --git a/src/common/Cryptography/Authentication/AuthCrypt.h b/src/common/Cryptography/Authentication/AuthCrypt.h
new file mode 100644
index 00000000000..b8913c95a2c
--- /dev/null
+++ b/src/common/Cryptography/Authentication/AuthCrypt.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _AUTHCRYPT_H
+#define _AUTHCRYPT_H
+
+#include "Cryptography/ARC4.h"
+
+class BigNumber;
+
+class AuthCrypt
+{
+ public:
+ AuthCrypt();
+
+ void Init(BigNumber* K);
+ void DecryptRecv(uint8 *, size_t);
+ void EncryptSend(uint8 *, size_t);
+
+ bool IsInitialized() const { return _initialized; }
+
+ private:
+ ARC4 _clientDecrypt;
+ ARC4 _serverEncrypt;
+ bool _initialized;
+};
+#endif
diff --git a/src/common/Cryptography/BigNumber.cpp b/src/common/Cryptography/BigNumber.cpp
new file mode 100644
index 00000000000..720e8e30441
--- /dev/null
+++ b/src/common/Cryptography/BigNumber.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Cryptography/BigNumber.h"
+#include <openssl/bn.h>
+#include <cstring>
+#include <algorithm>
+#include <memory>
+
+BigNumber::BigNumber()
+ : _bn(BN_new())
+{ }
+
+BigNumber::BigNumber(BigNumber const& bn)
+ : _bn(BN_dup(bn._bn))
+{ }
+
+BigNumber::BigNumber(uint32 val)
+ : _bn(BN_new())
+{
+ BN_set_word(_bn, val);
+}
+
+BigNumber::~BigNumber()
+{
+ BN_free(_bn);
+}
+
+void BigNumber::SetDword(uint32 val)
+{
+ BN_set_word(_bn, val);
+}
+
+void BigNumber::SetQword(uint64 val)
+{
+ BN_set_word(_bn, (uint32)(val >> 32));
+ BN_lshift(_bn, _bn, 32);
+ BN_add_word(_bn, (uint32)(val & 0xFFFFFFFF));
+}
+
+void BigNumber::SetBinary(uint8 const* bytes, int32 len)
+{
+ uint8* array = new uint8[len];
+
+ for (int i = 0; i < len; i++)
+ array[i] = bytes[len - 1 - i];
+
+ BN_bin2bn(array, len, _bn);
+
+ delete[] array;
+}
+
+void BigNumber::SetHexStr(char const* str)
+{
+ BN_hex2bn(&_bn, str);
+}
+
+void BigNumber::SetRand(int32 numbits)
+{
+ BN_rand(_bn, numbits, 0, 1);
+}
+
+BigNumber& BigNumber::operator=(BigNumber const& bn)
+{
+ if (this == &bn)
+ return *this;
+
+ BN_copy(_bn, bn._bn);
+ return *this;
+}
+
+BigNumber BigNumber::operator+=(BigNumber const& bn)
+{
+ BN_add(_bn, _bn, bn._bn);
+ return *this;
+}
+
+BigNumber BigNumber::operator-=(BigNumber const& bn)
+{
+ BN_sub(_bn, _bn, bn._bn);
+ return *this;
+}
+
+BigNumber BigNumber::operator*=(BigNumber const& bn)
+{
+ BN_CTX *bnctx;
+
+ bnctx = BN_CTX_new();
+ BN_mul(_bn, _bn, bn._bn, bnctx);
+ BN_CTX_free(bnctx);
+
+ return *this;
+}
+
+BigNumber BigNumber::operator/=(BigNumber const& bn)
+{
+ BN_CTX *bnctx;
+
+ bnctx = BN_CTX_new();
+ BN_div(_bn, NULL, _bn, bn._bn, bnctx);
+ BN_CTX_free(bnctx);
+
+ return *this;
+}
+
+BigNumber BigNumber::operator%=(BigNumber const& bn)
+{
+ BN_CTX *bnctx;
+
+ bnctx = BN_CTX_new();
+ BN_mod(_bn, _bn, bn._bn, bnctx);
+ BN_CTX_free(bnctx);
+
+ return *this;
+}
+
+BigNumber BigNumber::Exp(BigNumber const& bn)
+{
+ BigNumber ret;
+ BN_CTX *bnctx;
+
+ bnctx = BN_CTX_new();
+ BN_exp(ret._bn, _bn, bn._bn, bnctx);
+ BN_CTX_free(bnctx);
+
+ return ret;
+}
+
+BigNumber BigNumber::ModExp(BigNumber const& bn1, BigNumber const& bn2)
+{
+ BigNumber ret;
+ BN_CTX *bnctx;
+
+ bnctx = BN_CTX_new();
+ BN_mod_exp(ret._bn, _bn, bn1._bn, bn2._bn, bnctx);
+ BN_CTX_free(bnctx);
+
+ return ret;
+}
+
+int32 BigNumber::GetNumBytes(void)
+{
+ return BN_num_bytes(_bn);
+}
+
+uint32 BigNumber::AsDword()
+{
+ return (uint32)BN_get_word(_bn);
+}
+
+bool BigNumber::isZero() const
+{
+ return BN_is_zero(_bn);
+}
+
+std::unique_ptr<uint8[]> BigNumber::AsByteArray(int32 minSize, bool littleEndian)
+{
+ int numBytes = GetNumBytes();
+ int length = (minSize >= numBytes) ? minSize : numBytes;
+
+ uint8* array = new uint8[length];
+
+ // If we need more bytes than length of BigNumber set the rest to 0
+ if (length > numBytes)
+ memset((void*)array, 0, length);
+
+ BN_bn2bin(_bn, (unsigned char *)array);
+
+ // openssl's BN stores data internally in big endian format, reverse if little endian desired
+ if (littleEndian)
+ std::reverse(array, array + numBytes);
+
+ std::unique_ptr<uint8[]> ret(array);
+ return ret;
+}
+
+char * BigNumber::AsHexStr() const
+{
+ return BN_bn2hex(_bn);
+}
+
+char * BigNumber::AsDecStr() const
+{
+ return BN_bn2dec(_bn);
+}
+
diff --git a/src/common/Cryptography/BigNumber.h b/src/common/Cryptography/BigNumber.h
new file mode 100644
index 00000000000..e6a056b5baa
--- /dev/null
+++ b/src/common/Cryptography/BigNumber.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _AUTH_BIGNUMBER_H
+#define _AUTH_BIGNUMBER_H
+
+#include <memory>
+#include "Define.h"
+
+struct bignum_st;
+
+class BigNumber
+{
+ public:
+ BigNumber();
+ BigNumber(BigNumber const& bn);
+ BigNumber(uint32);
+ ~BigNumber();
+
+ void SetDword(uint32);
+ void SetQword(uint64);
+ void SetBinary(uint8 const* bytes, int32 len);
+ void SetHexStr(char const* str);
+
+ void SetRand(int32 numbits);
+
+ BigNumber& operator=(BigNumber const& bn);
+
+ BigNumber operator+=(BigNumber const& bn);
+ BigNumber operator+(BigNumber const& bn)
+ {
+ BigNumber t(*this);
+ return t += bn;
+ }
+
+ BigNumber operator-=(BigNumber const& bn);
+ BigNumber operator-(BigNumber const& bn)
+ {
+ BigNumber t(*this);
+ return t -= bn;
+ }
+
+ BigNumber operator*=(BigNumber const& bn);
+ BigNumber operator*(BigNumber const& bn)
+ {
+ BigNumber t(*this);
+ return t *= bn;
+ }
+
+ BigNumber operator/=(BigNumber const& bn);
+ BigNumber operator/(BigNumber const& bn)
+ {
+ BigNumber t(*this);
+ return t /= bn;
+ }
+
+ BigNumber operator%=(BigNumber const& bn);
+ BigNumber operator%(BigNumber const& bn)
+ {
+ BigNumber t(*this);
+ return t %= bn;
+ }
+
+ bool isZero() const;
+
+ BigNumber ModExp(BigNumber const& bn1, BigNumber const& bn2);
+ BigNumber Exp(BigNumber const&);
+
+ int32 GetNumBytes(void);
+
+ struct bignum_st *BN() { return _bn; }
+
+ uint32 AsDword();
+
+ std::unique_ptr<uint8[]> AsByteArray(int32 minSize = 0, bool littleEndian = true);
+
+ char * AsHexStr() const;
+ char * AsDecStr() const;
+
+ private:
+ struct bignum_st *_bn;
+
+};
+#endif
+
diff --git a/src/common/Cryptography/HMACSHA1.cpp b/src/common/Cryptography/HMACSHA1.cpp
new file mode 100644
index 00000000000..304633cbc03
--- /dev/null
+++ b/src/common/Cryptography/HMACSHA1.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "HMACSHA1.h"
+#include "BigNumber.h"
+#include "Common.h"
+
+HmacHash::HmacHash(uint32 len, uint8 *seed)
+{
+ HMAC_CTX_init(&m_ctx);
+ HMAC_Init_ex(&m_ctx, seed, len, EVP_sha1(), NULL);
+ memset(m_digest, 0, sizeof(m_digest));
+}
+
+HmacHash::~HmacHash()
+{
+ HMAC_CTX_cleanup(&m_ctx);
+}
+
+void HmacHash::UpdateData(const std::string &str)
+{
+ HMAC_Update(&m_ctx, (uint8 const*)str.c_str(), str.length());
+}
+
+void HmacHash::UpdateData(const uint8* data, size_t len)
+{
+ HMAC_Update(&m_ctx, data, len);
+}
+
+void HmacHash::Finalize()
+{
+ uint32 length = 0;
+ HMAC_Final(&m_ctx, (uint8*)m_digest, &length);
+ ASSERT(length == SHA_DIGEST_LENGTH);
+}
+
+uint8 *HmacHash::ComputeHash(BigNumber* bn)
+{
+ HMAC_Update(&m_ctx, bn->AsByteArray().get(), bn->GetNumBytes());
+ Finalize();
+ return (uint8*)m_digest;
+}
diff --git a/src/common/Cryptography/HMACSHA1.h b/src/common/Cryptography/HMACSHA1.h
new file mode 100644
index 00000000000..66cf214d9b1
--- /dev/null
+++ b/src/common/Cryptography/HMACSHA1.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _AUTH_HMAC_H
+#define _AUTH_HMAC_H
+
+#include "Define.h"
+#include <string>
+#include <openssl/hmac.h>
+#include <openssl/sha.h>
+
+class BigNumber;
+
+#define SEED_KEY_SIZE 16
+
+class HmacHash
+{
+ public:
+ HmacHash(uint32 len, uint8 *seed);
+ ~HmacHash();
+ void UpdateData(const std::string &str);
+ void UpdateData(const uint8* data, size_t len);
+ void Finalize();
+ uint8 *ComputeHash(BigNumber* bn);
+ uint8 *GetDigest() { return (uint8*)m_digest; }
+ int GetLength() const { return SHA_DIGEST_LENGTH; }
+ private:
+ HMAC_CTX m_ctx;
+ uint8 m_digest[SHA_DIGEST_LENGTH];
+};
+#endif
+
diff --git a/src/common/Cryptography/OpenSSLCrypto.cpp b/src/common/Cryptography/OpenSSLCrypto.cpp
new file mode 100644
index 00000000000..f122888292f
--- /dev/null
+++ b/src/common/Cryptography/OpenSSLCrypto.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <OpenSSLCrypto.h>
+#include <openssl/crypto.h>
+#include <vector>
+#include <thread>
+#include <mutex>
+
+std::vector<std::mutex*> cryptoLocks;
+
+static void lockingCallback(int mode, int type, const char* /*file*/, int /*line*/)
+{
+ if (mode & CRYPTO_LOCK)
+ cryptoLocks[type]->lock();
+ else
+ cryptoLocks[type]->unlock();
+}
+
+static void threadIdCallback(CRYPTO_THREADID * id)
+{
+ CRYPTO_THREADID_set_numeric(id, std::hash<std::thread::id>()(std::this_thread::get_id()));
+}
+
+void OpenSSLCrypto::threadsSetup()
+{
+ cryptoLocks.resize(CRYPTO_num_locks());
+ for(int i = 0 ; i < CRYPTO_num_locks(); ++i)
+ {
+ cryptoLocks[i] = new std::mutex;
+ }
+ CRYPTO_THREADID_set_callback(threadIdCallback);
+ CRYPTO_set_locking_callback(lockingCallback);
+}
+
+void OpenSSLCrypto::threadsCleanup()
+{
+ CRYPTO_set_locking_callback(NULL);
+ CRYPTO_THREADID_set_callback(NULL);
+ for(int i = 0 ; i < CRYPTO_num_locks(); ++i)
+ {
+ delete cryptoLocks[i];
+ }
+ cryptoLocks.resize(0);
+}
diff --git a/src/common/Cryptography/OpenSSLCrypto.h b/src/common/Cryptography/OpenSSLCrypto.h
new file mode 100644
index 00000000000..0daa20c4780
--- /dev/null
+++ b/src/common/Cryptography/OpenSSLCrypto.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef OPENSSL_CRYPTO_H
+#define OPENSSL_CRYPTO_H
+
+/**
+* A group of functions which setup openssl crypto module to work properly in multithreaded enviroment
+* If not setup properly - it will crash
+*/
+namespace OpenSSLCrypto
+{
+ /// Needs to be called before threads using openssl are spawned
+ void threadsSetup();
+ /// Needs to be called after threads using openssl are despawned
+ void threadsCleanup();
+}
+
+#endif \ No newline at end of file
diff --git a/src/common/Cryptography/SHA1.cpp b/src/common/Cryptography/SHA1.cpp
new file mode 100644
index 00000000000..bd7101075de
--- /dev/null
+++ b/src/common/Cryptography/SHA1.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "SHA1.h"
+#include "BigNumber.h"
+#include <cstring>
+#include <stdarg.h>
+
+SHA1Hash::SHA1Hash()
+{
+ SHA1_Init(&mC);
+ memset(mDigest, 0, SHA_DIGEST_LENGTH * sizeof(uint8));
+}
+
+SHA1Hash::~SHA1Hash()
+{
+ SHA1_Init(&mC);
+}
+
+void SHA1Hash::UpdateData(const uint8 *dta, int len)
+{
+ SHA1_Update(&mC, dta, len);
+}
+
+void SHA1Hash::UpdateData(const std::string &str)
+{
+ UpdateData((uint8 const*)str.c_str(), str.length());
+}
+
+void SHA1Hash::UpdateBigNumbers(BigNumber* bn0, ...)
+{
+ va_list v;
+ BigNumber* bn;
+
+ va_start(v, bn0);
+ bn = bn0;
+ while (bn)
+ {
+ UpdateData(bn->AsByteArray().get(), bn->GetNumBytes());
+ bn = va_arg(v, BigNumber*);
+ }
+ va_end(v);
+}
+
+void SHA1Hash::Initialize()
+{
+ SHA1_Init(&mC);
+}
+
+void SHA1Hash::Finalize(void)
+{
+ SHA1_Final(mDigest, &mC);
+}
+
diff --git a/src/common/Cryptography/SHA1.h b/src/common/Cryptography/SHA1.h
new file mode 100644
index 00000000000..f59bdc25556
--- /dev/null
+++ b/src/common/Cryptography/SHA1.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _AUTH_SHA1_H
+#define _AUTH_SHA1_H
+
+#include "Define.h"
+#include <string>
+#include <openssl/sha.h>
+
+class BigNumber;
+
+class SHA1Hash
+{
+ public:
+ SHA1Hash();
+ ~SHA1Hash();
+
+ void UpdateBigNumbers(BigNumber* bn0, ...);
+
+ void UpdateData(const uint8 *dta, int len);
+ void UpdateData(const std::string &str);
+
+ void Initialize();
+ void Finalize();
+
+ uint8 *GetDigest(void) { return mDigest; }
+ int GetLength(void) const { return SHA_DIGEST_LENGTH; }
+
+ private:
+ SHA_CTX mC;
+ uint8 mDigest[SHA_DIGEST_LENGTH];
+};
+#endif
+
diff --git a/src/common/Cryptography/WardenKeyGeneration.h b/src/common/Cryptography/WardenKeyGeneration.h
new file mode 100644
index 00000000000..bfa0337d347
--- /dev/null
+++ b/src/common/Cryptography/WardenKeyGeneration.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "SHA1.h"
+
+#include <cstring>
+
+#ifndef _WARDEN_KEY_GENERATION_H
+#define _WARDEN_KEY_GENERATION_H
+
+class SHA1Randx
+{
+public:
+ SHA1Randx(uint8* buff, uint32 size)
+ {
+ uint32 halfSize = size / 2;
+
+ sh.Initialize();
+ sh.UpdateData(buff, halfSize);
+ sh.Finalize();
+
+ memcpy(o1, sh.GetDigest(), 20);
+
+ sh.Initialize();
+ sh.UpdateData(buff + halfSize, size - halfSize);
+ sh.Finalize();
+
+ memcpy(o2, sh.GetDigest(), 20);
+
+ memset(o0, 0x00, 20);
+
+ FillUp();
+ }
+
+ void Generate(uint8* buf, uint32 sz)
+ {
+ for (uint32 i = 0; i < sz; ++i)
+ {
+ if (taken == 20)
+ FillUp();
+
+ buf[i] = o0[taken];
+ taken++;
+ }
+ }
+
+private:
+ void FillUp()
+ {
+ sh.Initialize();
+ sh.UpdateData(o1, 20);
+ sh.UpdateData(o0, 20);
+ sh.UpdateData(o2, 20);
+ sh.Finalize();
+
+ memcpy(o0, sh.GetDigest(), 20);
+
+ taken = 0;
+ }
+
+ SHA1Hash sh;
+ uint32 taken;
+ uint8 o0[20], o1[20], o2[20];
+};
+
+#endif