summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2011-08-12 17:29:21 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-08-12 17:32:17 (GMT)
commitc6ffcd27e94d2f90fd4a3bcb5d2d3c6550ead59c (patch)
tree5968399a0d1ae73c1f197630bef3a0960e8525b5
parent08cfaa06859238449d6848df4e170ffb6dc605d3 (diff)
downloadswift-c6ffcd27e94d2f90fd4a3bcb5d2d3c6550ead59c.zip
swift-c6ffcd27e94d2f90fd4a3bcb5d2d3c6550ead59c.tar.bz2
Refactored stringcodec functions to make them independent of hash algos.
-rw-r--r--Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp13
-rw-r--r--Swiften/SConscript4
-rw-r--r--Swiften/StringCodecs/HMAC.h57
-rw-r--r--Swiften/StringCodecs/HMACSHA1.cpp95
-rw-r--r--Swiften/StringCodecs/HMACSHA1.h18
-rw-r--r--Swiften/StringCodecs/PBKDF2.cpp27
-rw-r--r--Swiften/StringCodecs/PBKDF2.h17
-rw-r--r--Swiften/StringCodecs/SHA1.h9
-rw-r--r--Swiften/StringCodecs/UnitTest/HMACTest.cpp (renamed from Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp)11
-rw-r--r--Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp8
10 files changed, 100 insertions, 159 deletions
diff --git a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp
index 20b3d8a..bcd6c5d 100644
--- a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp
+++ b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp
@@ -12,7 +12,8 @@
#include <Swiften/StringCodecs/SHA1.h>
#include <Swiften/StringCodecs/Base64.h>
-#include <Swiften/StringCodecs/HMACSHA1.h>
+#include <Swiften/StringCodecs/HMAC.h>
+#include <Swiften/StringCodecs/SHA1.h>
#include <Swiften/StringCodecs/PBKDF2.h>
#include <Swiften/IDN/StringPrep.h>
#include <Swiften/Base/Concat.h>
@@ -44,9 +45,9 @@ boost::optional<SafeByteArray> SCRAMSHA1ClientAuthenticator::getResponse() const
return createSafeByteArray(concat(getGS2Header(), getInitialBareClientMessage()));
}
else if (step == Proof) {
- ByteArray clientKey = HMACSHA1::getResult(saltedPassword, createByteArray("Client Key"));
+ ByteArray clientKey = HMAC<SHA1>()(saltedPassword, createByteArray("Client Key"));
ByteArray storedKey = SHA1::getHash(clientKey);
- ByteArray clientSignature = HMACSHA1::getResult(createSafeByteArray(storedKey), authMessage);
+ ByteArray clientSignature = HMAC<SHA1>()(createSafeByteArray(storedKey), authMessage);
ByteArray clientProof = clientKey;
for (unsigned int i = 0; i < clientProof.size(); ++i) {
clientProof[i] ^= clientSignature[i];
@@ -101,13 +102,13 @@ bool SCRAMSHA1ClientAuthenticator::setChallenge(const boost::optional<ByteArray>
// Compute all the values needed for the server signature
try {
- saltedPassword = PBKDF2::encode(StringPrep::getPrepared(getPassword(), StringPrep::SASLPrep), salt, iterations);
+ saltedPassword = PBKDF2::encode<HMAC<SHA1> >(StringPrep::getPrepared(getPassword(), StringPrep::SASLPrep), salt, iterations);
}
catch (const std::exception&) {
}
authMessage = concat(getInitialBareClientMessage(), createByteArray(","), initialServerMessage, createByteArray(","), getFinalMessageWithoutProof());
- ByteArray serverKey = HMACSHA1::getResult(saltedPassword, createByteArray("Server Key"));
- serverSignature = HMACSHA1::getResult(serverKey, authMessage);
+ ByteArray serverKey = HMAC<SHA1>()(saltedPassword, createByteArray("Server Key"));
+ serverSignature = HMAC<SHA1>()(serverKey, authMessage);
step = Proof;
return true;
diff --git a/Swiften/SConscript b/Swiften/SConscript
index 6d38717..6d2d14a 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -175,9 +175,7 @@ if env["SCONS_STAGE"] == "build" :
"Session/BasicSessionStream.cpp",
"StringCodecs/Base64.cpp",
"StringCodecs/SHA1.cpp",
- "StringCodecs/HMACSHA1.cpp",
"StringCodecs/MD5.cpp",
- "StringCodecs/PBKDF2.cpp",
"StringCodecs/Hexify.cpp",
]
@@ -349,7 +347,7 @@ if env["SCONS_STAGE"] == "build" :
File("StringCodecs/UnitTest/SHA1Test.cpp"),
File("StringCodecs/UnitTest/MD5Test.cpp"),
File("StringCodecs/UnitTest/HexifyTest.cpp"),
- File("StringCodecs/UnitTest/HMACSHA1Test.cpp"),
+ File("StringCodecs/UnitTest/HMACTest.cpp"),
File("StringCodecs/UnitTest/PBKDF2Test.cpp"),
File("TLS/UnitTest/ServerIdentityVerifierTest.cpp"),
File("TLS/UnitTest/CertificateTest.cpp"),
diff --git a/Swiften/StringCodecs/HMAC.h b/Swiften/StringCodecs/HMAC.h
new file mode 100644
index 0000000..438a3a7
--- /dev/null
+++ b/Swiften/StringCodecs/HMAC.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/Algorithm.h>
+#include <cassert>
+
+namespace Swift {
+ namespace HMAC_Detail {
+ static const unsigned int B = 64;
+
+ template<typename Hash, typename KeyType>
+ static ByteArray getHMAC(const KeyType& key, const ByteArray& data) {
+ assert(key.size() <= B);
+ Hash hash;
+
+ // Create the padded key
+ KeyType paddedKey(key);
+ paddedKey.resize(B, 0x0);
+
+ // Create the first value
+ KeyType x(paddedKey);
+ for (unsigned int i = 0; i < x.size(); ++i) {
+ x[i] ^= 0x36;
+ }
+ append(x, data);
+
+ // Create the second value
+ KeyType y(paddedKey);
+ for (unsigned int i = 0; i < y.size(); ++i) {
+ y[i] ^= 0x5c;
+ }
+ append(y, hash(x));
+
+ return hash(y);
+ }
+ };
+
+ template<typename Hash>
+ class HMAC {
+ private:
+
+ public:
+ ByteArray operator()(const ByteArray& key, const ByteArray& data) const {
+ return HMAC_Detail::getHMAC<Hash,ByteArray>(key, data);
+ }
+
+ ByteArray operator()(const SafeByteArray& key, const ByteArray& data) const {
+ return HMAC_Detail::getHMAC<Hash,SafeByteArray>(key, data);
+ }
+ };
+}
diff --git a/Swiften/StringCodecs/HMACSHA1.cpp b/Swiften/StringCodecs/HMACSHA1.cpp
deleted file mode 100644
index fd951ae..0000000
--- a/Swiften/StringCodecs/HMACSHA1.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include <Swiften/StringCodecs/HMACSHA1.h>
-
-#include <cassert>
-
-#include <Swiften/StringCodecs/SHA1.h>
-#include <Swiften/Base/Algorithm.h>
-
-using namespace Swift;
-
-namespace {
- static const unsigned int B = 64;
-
- template<typename SourceType>
- ByteArray getHMACSHA1(const SourceType& key, const ByteArray& data) {
- assert(key.size() <= B);
-
- // Create the padded key
- SourceType paddedKey(key);
- paddedKey.resize(B, 0x0);
-
- // Create the first value
- SourceType x(paddedKey);
- for (unsigned int i = 0; i < x.size(); ++i) {
- x[i] ^= 0x36;
- }
- append(x, data);
-
- // Create the second value
- SourceType y(paddedKey);
- for (unsigned int i = 0; i < y.size(); ++i) {
- y[i] ^= 0x5c;
- }
- append(y, SHA1::getHash(x));
-
- return SHA1::getHash(y);
- }
-}
-
-namespace Swift {
-
-ByteArray HMACSHA1::getResult(const SafeByteArray& key, const ByteArray& data) {
- return getHMACSHA1(key, data);
-}
-
-ByteArray HMACSHA1::getResult(const ByteArray& key, const ByteArray& data) {
- return getHMACSHA1(key, data);
-}
-
-
-
-#if 0
-
-// A tweaked version of HMACSHA1 that is more than twice as fast as the one above.
-// After this, more than 80% is spent in SHA1.
-// Optimizations:
-// - Avoids using ByteArray/std::vector
-// - Uses openssl's SHA1, which is slightly faster
-// - Does 'xor' on word basis
-// - Passes return value as a parameter
-
-#include <openssl/sha.h>
-
-void HMACSHA1::getResult(const ByteArray& key, const ByteArray& data, ByteArray& result) {
- // Create first value
- size_t xSize = B + data.size();
- unsigned char* x = (unsigned char*) malloc(xSize * sizeof(unsigned char));
- memset(x, 0, B);
- memcpy(x, key.getData(), key.size());
- for (unsigned int i = 0; i < (B>>32); ++i) {
- x[i<<32] ^= 0x36363636;
- }
- memcpy(x + B, data.getData(), data.size());
-
- // Create the second value
- unsigned char y[B + 20];
- memset(y, 0, B);
- memcpy(y, key.getData(), key.size());
- for (unsigned int i = 0; i < (B>>32); ++i) {
- y[i<<32] ^= 0x5c5c5c5c;
- }
- ::SHA1(x, xSize, y + B);
- free(x);
-
- ::SHA1(y, B + 20, (unsigned char*) result.getData());
-}
-
-#endif
-
-}
diff --git a/Swiften/StringCodecs/HMACSHA1.h b/Swiften/StringCodecs/HMACSHA1.h
deleted file mode 100644
index 0463e64..0000000
--- a/Swiften/StringCodecs/HMACSHA1.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include <Swiften/Base/ByteArray.h>
-#include <Swiften/Base/SafeByteArray.h>
-
-namespace Swift {
- class HMACSHA1 {
- public:
- static ByteArray getResult(const SafeByteArray& key, const ByteArray& data);
- static ByteArray getResult(const ByteArray& key, const ByteArray& data);
- };
-}
diff --git a/Swiften/StringCodecs/PBKDF2.cpp b/Swiften/StringCodecs/PBKDF2.cpp
deleted file mode 100644
index 81e1208..0000000
--- a/Swiften/StringCodecs/PBKDF2.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include <Swiften/StringCodecs/PBKDF2.h>
-#include <Swiften/StringCodecs/HMACSHA1.h>
-#include <Swiften/Base/Concat.h>
-
-namespace Swift {
-
-ByteArray PBKDF2::encode(const SafeByteArray& password, const ByteArray& salt, int iterations) {
- ByteArray u = HMACSHA1::getResult(password, concat(salt, createByteArray("\0\0\0\1", 4)));
- ByteArray result(u);
- int i = 1;
- while (i < iterations) {
- u = HMACSHA1::getResult(password, u);
- for (unsigned int j = 0; j < u.size(); ++j) {
- result[j] ^= u[j];
- }
- ++i;
- }
- return result;
-}
-
-}
diff --git a/Swiften/StringCodecs/PBKDF2.h b/Swiften/StringCodecs/PBKDF2.h
index b1a5986..0c04145 100644
--- a/Swiften/StringCodecs/PBKDF2.h
+++ b/Swiften/StringCodecs/PBKDF2.h
@@ -7,10 +7,25 @@
#pragma once
#include <Swiften/Base/SafeByteArray.h>
+#include <Swiften/Base/Concat.h>
namespace Swift {
class PBKDF2 {
public:
- static ByteArray encode(const SafeByteArray& password, const ByteArray& salt, int iterations);
+ template<typename PRF>
+ static ByteArray encode(const SafeByteArray& password, const ByteArray& salt, int iterations) {
+ PRF prf;
+ ByteArray u = prf(password, concat(salt, createByteArray("\0\0\0\1", 4)));
+ ByteArray result(u);
+ int i = 1;
+ while (i < iterations) {
+ u = prf(password, u);
+ for (unsigned int j = 0; j < u.size(); ++j) {
+ result[j] ^= u[j];
+ }
+ ++i;
+ }
+ return result;
+ }
};
}
diff --git a/Swiften/StringCodecs/SHA1.h b/Swiften/StringCodecs/SHA1.h
index 25bfa54..19488cb 100644
--- a/Swiften/StringCodecs/SHA1.h
+++ b/Swiften/StringCodecs/SHA1.h
@@ -26,9 +26,16 @@ namespace Swift {
* convenient.
*/
static ByteArray getHash(const ByteArray& data);
-
static ByteArray getHash(const SafeByteArray& data);
+ ByteArray operator()(const SafeByteArray& data) {
+ return getHash(data);
+ }
+
+ ByteArray operator()(const ByteArray& data) {
+ return getHash(data);
+ }
+
private:
typedef struct {
boost::uint32_t state[5];
diff --git a/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp b/Swiften/StringCodecs/UnitTest/HMACTest.cpp
index d8cba42..bdb0d96 100644
--- a/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp
+++ b/Swiften/StringCodecs/UnitTest/HMACTest.cpp
@@ -11,20 +11,21 @@
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <Swiften/Base/ByteArray.h>
-#include <Swiften/StringCodecs/HMACSHA1.h>
+#include <Swiften/StringCodecs/HMAC.h>
+#include <Swiften/StringCodecs/SHA1.h>
using namespace Swift;
-class HMACSHA1Test : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(HMACSHA1Test);
+class HMACTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(HMACTest);
CPPUNIT_TEST(testGetResult);
CPPUNIT_TEST_SUITE_END();
public:
void testGetResult() {
- ByteArray result(HMACSHA1::getResult(createSafeByteArray("foo"), createByteArray("foobar")));
+ ByteArray result(HMAC<SHA1>()(createSafeByteArray("foo"), createByteArray("foobar")));
CPPUNIT_ASSERT_EQUAL(createByteArray("\xa4\xee\xba\x8e\x63\x3d\x77\x88\x69\xf5\x68\xd0\x5a\x1b\x3d\xc7\x2b\xfd\x4\xdd"), result);
}
};
-CPPUNIT_TEST_SUITE_REGISTRATION(HMACSHA1Test);
+CPPUNIT_TEST_SUITE_REGISTRATION(HMACTest);
diff --git a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp
index d0aacd3..377e5c9 100644
--- a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp
+++ b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp
@@ -12,6 +12,8 @@
#include <Swiften/Base/ByteArray.h>
#include <Swiften/StringCodecs/PBKDF2.h>
+#include <Swiften/StringCodecs/HMAC.h>
+#include <Swiften/StringCodecs/SHA1.h>
using namespace Swift;
@@ -24,19 +26,19 @@ class PBKDF2Test : public CppUnit::TestFixture {
public:
void testGetResult_I1() {
- ByteArray result(PBKDF2::encode(createSafeByteArray("password"), createByteArray("salt"), 1));
+ ByteArray result(PBKDF2::encode<HMAC<SHA1> >(createSafeByteArray("password"), createByteArray("salt"), 1));
CPPUNIT_ASSERT_EQUAL(createByteArray("\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6"), result);
}
void testGetResult_I2() {
- ByteArray result(PBKDF2::encode(createSafeByteArray("password"), createByteArray("salt"), 2));
+ ByteArray result(PBKDF2::encode<HMAC<SHA1> >(createSafeByteArray("password"), createByteArray("salt"), 2));
CPPUNIT_ASSERT_EQUAL(createByteArray("\xea\x6c\x1\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57"), result);
}
void testGetResult_I4096() {
- ByteArray result(PBKDF2::encode(createSafeByteArray("password"), createByteArray("salt"), 4096));
+ ByteArray result(PBKDF2::encode<HMAC<SHA1> >(createSafeByteArray("password"), createByteArray("salt"), 4096));
CPPUNIT_ASSERT_EQUAL(createByteArray("\x4b\x00\x79\x1\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1", 20), result);
}