aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/shared')
-rw-r--r--src/server/shared/Cryptography/BigNumber.cpp43
-rw-r--r--src/server/shared/Cryptography/BigNumber.h9
-rw-r--r--src/server/shared/Cryptography/HMACSHA1.cpp2
-rw-r--r--src/server/shared/Cryptography/OpenSSLCrypto.cpp59
-rw-r--r--src/server/shared/Cryptography/OpenSSLCrypto.h33
-rw-r--r--src/server/shared/Cryptography/SHA1.cpp2
6 files changed, 118 insertions, 30 deletions
diff --git a/src/server/shared/Cryptography/BigNumber.cpp b/src/server/shared/Cryptography/BigNumber.cpp
index 06ea57b662e..38c274b7555 100644
--- a/src/server/shared/Cryptography/BigNumber.cpp
+++ b/src/server/shared/Cryptography/BigNumber.cpp
@@ -22,17 +22,18 @@
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <algorithm>
+#include <ace/Auto_Ptr.h>
BigNumber::BigNumber()
- : _bn(BN_new()), _array(NULL)
+ : _bn(BN_new())
{ }
BigNumber::BigNumber(BigNumber const& bn)
- : _bn(BN_dup(bn._bn)), _array(NULL)
+ : _bn(BN_dup(bn._bn))
{ }
BigNumber::BigNumber(uint32 val)
- : _bn(BN_new()), _array(NULL)
+ : _bn(BN_new())
{
BN_set_word(_bn, val);
}
@@ -40,7 +41,6 @@ BigNumber::BigNumber(uint32 val)
BigNumber::~BigNumber()
{
BN_free(_bn);
- delete[] _array;
}
void BigNumber::SetDword(uint32 val)
@@ -50,16 +50,21 @@ void BigNumber::SetDword(uint32 val)
void BigNumber::SetQword(uint64 val)
{
- BN_add_word(_bn, (uint32)(val >> 32));
+ 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 t[1000];
- for (int i = 0; i < len; i++) t[i] = bytes[len - 1 - i];
- BN_bin2bn(t, len, _bn);
+ 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)
@@ -165,29 +170,23 @@ bool BigNumber::isZero() const
return BN_is_zero(_bn);
}
-uint8* BigNumber::AsByteArray(int32 minSize, bool reverse)
+ACE_Auto_Array_Ptr<uint8> BigNumber::AsByteArray(int32 minSize, bool littleEndian)
{
int length = (minSize >= GetNumBytes()) ? minSize : GetNumBytes();
- ACE_GUARD_RETURN(ACE_Mutex, g, _lock, 0);
-
- if (_array)
- {
- delete[] _array;
- _array = NULL;
- }
- _array = new uint8[length];
+ uint8* array = new uint8[length];
// If we need more bytes than length of BigNumber set the rest to 0
if (length > GetNumBytes())
- memset((void*)_array, 0, length);
+ memset((void*)array, 0, length);
- BN_bn2bin(_bn, (unsigned char *)_array);
+ BN_bn2bin(_bn, (unsigned char *)array);
- if (reverse)
- std::reverse(_array, _array + length);
+ // openssl's BN stores data internally in big endian format, reverse if little endian desired
+ if (littleEndian)
+ std::reverse(array, array + length);
- return _array;
+ return ACE_Auto_Array_Ptr<uint8>(array);
}
char * BigNumber::AsHexStr() const
diff --git a/src/server/shared/Cryptography/BigNumber.h b/src/server/shared/Cryptography/BigNumber.h
index fe56fd7e6f9..6129a24d1bc 100644
--- a/src/server/shared/Cryptography/BigNumber.h
+++ b/src/server/shared/Cryptography/BigNumber.h
@@ -20,7 +20,7 @@
#define _AUTH_BIGNUMBER_H
#include "Define.h"
-#include <ace/Mutex.h>
+#include <ace/Auto_Ptr.h>
struct bignum_st;
@@ -86,17 +86,14 @@ class BigNumber
struct bignum_st *BN() { return _bn; }
uint32 AsDword();
- uint8* AsByteArray(int32 minSize = 0, bool reverse = true);
+
+ ACE_Auto_Array_Ptr<uint8> AsByteArray(int32 minSize = 0, bool littleEndian = true);
char * AsHexStr() const;
char * AsDecStr() const;
private:
struct bignum_st *_bn;
- uint8 *_array;
-
- // This mutex only controls thread-safe access to AsByteArray() and should be replaced with a thread-safe implementation of BigNumber
- ACE_Mutex _lock;
};
#endif
diff --git a/src/server/shared/Cryptography/HMACSHA1.cpp b/src/server/shared/Cryptography/HMACSHA1.cpp
index 297b4e90316..62d1997ded2 100644
--- a/src/server/shared/Cryptography/HMACSHA1.cpp
+++ b/src/server/shared/Cryptography/HMACSHA1.cpp
@@ -45,7 +45,7 @@ void HmacHash::Finalize()
uint8 *HmacHash::ComputeHash(BigNumber* bn)
{
- HMAC_Update(&m_ctx, bn->AsByteArray(), bn->GetNumBytes());
+ HMAC_Update(&m_ctx, bn->AsByteArray().get(), bn->GetNumBytes());
Finalize();
return (uint8*)m_digest;
}
diff --git a/src/server/shared/Cryptography/OpenSSLCrypto.cpp b/src/server/shared/Cryptography/OpenSSLCrypto.cpp
new file mode 100644
index 00000000000..12169433615
--- /dev/null
+++ b/src/server/shared/Cryptography/OpenSSLCrypto.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008-2013 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 <ace/Thread_Mutex.h>
+#include <vector>
+#include <ace/Thread.h>
+
+std::vector<ACE_Thread_Mutex*> cryptoLocks;
+
+void lockingCallback(int mode, int type, const char *file, int line)
+{
+ if (mode & CRYPTO_LOCK)
+ cryptoLocks[type]->acquire();
+ else
+ cryptoLocks[type]->release();
+}
+
+void threadIdCallback(CRYPTO_THREADID * id)
+{
+ CRYPTO_THREADID_set_numeric(id, ACE_Thread::self());
+}
+
+void OpenSSLCrypto::threadsSetup()
+{
+ cryptoLocks.resize(CRYPTO_num_locks());
+ for(int i = 0 ; i < CRYPTO_num_locks(); ++i)
+ {
+ cryptoLocks[i] = new ACE_Thread_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);
+} \ No newline at end of file
diff --git a/src/server/shared/Cryptography/OpenSSLCrypto.h b/src/server/shared/Cryptography/OpenSSLCrypto.h
new file mode 100644
index 00000000000..70071007c5f
--- /dev/null
+++ b/src/server/shared/Cryptography/OpenSSLCrypto.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008-2013 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/server/shared/Cryptography/SHA1.cpp b/src/server/shared/Cryptography/SHA1.cpp
index 00d7e520d51..1f65c88a6f3 100644
--- a/src/server/shared/Cryptography/SHA1.cpp
+++ b/src/server/shared/Cryptography/SHA1.cpp
@@ -50,7 +50,7 @@ void SHA1Hash::UpdateBigNumbers(BigNumber* bn0, ...)
bn = bn0;
while (bn)
{
- UpdateData(bn->AsByteArray(), bn->GetNumBytes());
+ UpdateData(bn->AsByteArray().get(), bn->GetNumBytes());
bn = va_arg(v, BigNumber*);
}
va_end(v);