diff options
author | Remko Tronçon <git@el-tramo.be> | 2011-05-18 13:45:41 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2011-05-18 14:24:28 (GMT) |
commit | 23fa0f462ddd0c686c677bfe5d4d743621432b7e (patch) | |
tree | b8f0ea1860640f89eafba2460cc5d45bf28fc77c /Swiften/StringCodecs | |
parent | 2456a8b12163b3249b6b9164b601c36772eb05a1 (diff) | |
download | swift-contrib-23fa0f462ddd0c686c677bfe5d4d743621432b7e.zip swift-contrib-23fa0f462ddd0c686c677bfe5d4d743621432b7e.tar.bz2 |
Introduce safe containers for storing passwords.
Diffstat (limited to 'Swiften/StringCodecs')
-rw-r--r-- | Swiften/StringCodecs/Base64.cpp | 68 | ||||
-rw-r--r-- | Swiften/StringCodecs/Base64.h | 3 | ||||
-rw-r--r-- | Swiften/StringCodecs/HMACSHA1.cpp | 54 | ||||
-rw-r--r-- | Swiften/StringCodecs/HMACSHA1.h | 2 | ||||
-rw-r--r-- | Swiften/StringCodecs/MD5.cpp | 27 | ||||
-rw-r--r-- | Swiften/StringCodecs/MD5.h | 2 | ||||
-rw-r--r-- | Swiften/StringCodecs/PBKDF2.cpp | 2 | ||||
-rw-r--r-- | Swiften/StringCodecs/PBKDF2.h | 4 | ||||
-rw-r--r-- | Swiften/StringCodecs/SHA1.cpp | 14 | ||||
-rw-r--r-- | Swiften/StringCodecs/SHA1.h | 5 | ||||
-rw-r--r-- | Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp | 2 | ||||
-rw-r--r-- | Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp | 6 |
12 files changed, 124 insertions, 65 deletions
diff --git a/Swiften/StringCodecs/Base64.cpp b/Swiften/StringCodecs/Base64.cpp index 4ec2e16..d8511b4 100644 --- a/Swiften/StringCodecs/Base64.cpp +++ b/Swiften/StringCodecs/Base64.cpp @@ -10,42 +10,54 @@ #include <Swiften/StringCodecs/Base64.h> #include <Swiften/Base/Algorithm.h> +#include <Swiften/Base/SafeString.h> namespace Swift { #pragma GCC diagnostic ignored "-Wold-style-cast" -std::string Base64::encode(const ByteArray &s) { - int i; - int len = s.size(); - char tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - int a, b, c; - - std::string p; - p.resize((len+2)/3*4); - int at = 0; - for( i = 0; i < len; i += 3 ) { - a = ((unsigned char) (s[i]) & 3) << 4; - if(i + 1 < len) { - a += (unsigned char) (s[i + 1]) >> 4; - b = ((unsigned char) (s[i + 1]) & 0xF) << 2; - if(i + 2 < len) { - b += (unsigned char) (s[i + 2]) >> 6; - c = (unsigned char) (s[i + 2]) & 0x3F; +namespace { + template<typename TargetType, typename SourceType> + TargetType base64Encode(const SourceType& s) { + int i; + int len = s.size(); + char tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + int a, b, c; + + TargetType p; + p.resize((len+2)/3*4); + int at = 0; + for( i = 0; i < len; i += 3 ) { + a = ((unsigned char) (s[i]) & 3) << 4; + if(i + 1 < len) { + a += (unsigned char) (s[i + 1]) >> 4; + b = ((unsigned char) (s[i + 1]) & 0xF) << 2; + if(i + 2 < len) { + b += (unsigned char) (s[i + 2]) >> 6; + c = (unsigned char) (s[i + 2]) & 0x3F; + } + else + c = 64; + } + else { + b = c = 64; } - else - c = 64; - } - else { - b = c = 64; - } - p[at++] = tbl[(unsigned char) (s[i]) >> 2]; - p[at++] = tbl[a]; - p[at++] = tbl[b]; - p[at++] = tbl[c]; + p[at++] = tbl[(unsigned char) (s[i]) >> 2]; + p[at++] = tbl[a]; + p[at++] = tbl[b]; + p[at++] = tbl[c]; + } + return p; } - return p; +} + +std::string Base64::encode(const ByteArray &s) { + return base64Encode<std::string, ByteArray>(s); +} + +SafeString Base64::encode(const SafeByteArray &s) { + return base64Encode<SafeString, SafeByteArray>(s); } ByteArray Base64::decode(const std::string& input) { diff --git a/Swiften/StringCodecs/Base64.h b/Swiften/StringCodecs/Base64.h index 3b14595..00a290d 100644 --- a/Swiften/StringCodecs/Base64.h +++ b/Swiften/StringCodecs/Base64.h @@ -10,11 +10,14 @@ #include <string> #include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class Base64 { public: static std::string encode(const ByteArray& s); + static SafeString encode(const SafeByteArray& s); + static ByteArray decode(const std::string &s); }; } diff --git a/Swiften/StringCodecs/HMACSHA1.cpp b/Swiften/StringCodecs/HMACSHA1.cpp index e583e3b..fd951ae 100644 --- a/Swiften/StringCodecs/HMACSHA1.cpp +++ b/Swiften/StringCodecs/HMACSHA1.cpp @@ -9,37 +9,51 @@ #include <cassert> #include <Swiften/StringCodecs/SHA1.h> -#include <Swiften/Base/ByteArray.h> #include <Swiften/Base/Algorithm.h> -namespace Swift { +using namespace Swift; -static const unsigned int B = 64; +namespace { + static const unsigned int B = 64; -ByteArray HMACSHA1::getResult(const ByteArray& key, const ByteArray& data) { - assert(key.size() <= B); + template<typename SourceType> + ByteArray getHMACSHA1(const SourceType& key, const ByteArray& data) { + assert(key.size() <= B); - // Create the padded key - ByteArray paddedKey(key); - paddedKey.resize(B, 0x0); + // Create the padded key + SourceType paddedKey(key); + paddedKey.resize(B, 0x0); - // Create the first value - ByteArray x(paddedKey); - for (unsigned int i = 0; i < x.size(); ++i) { - x[i] ^= 0x36; - } - append(x, data); + // 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 - ByteArray y(paddedKey); - for (unsigned int i = 0; i < y.size(); ++i) { - y[i] ^= 0x5c; + // 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); } - 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. diff --git a/Swiften/StringCodecs/HMACSHA1.h b/Swiften/StringCodecs/HMACSHA1.h index 39c6e4e..0463e64 100644 --- a/Swiften/StringCodecs/HMACSHA1.h +++ b/Swiften/StringCodecs/HMACSHA1.h @@ -7,10 +7,12 @@ #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/MD5.cpp b/Swiften/StringCodecs/MD5.cpp index 9e69172..159eb87 100644 --- a/Swiften/StringCodecs/MD5.cpp +++ b/Swiften/StringCodecs/MD5.cpp @@ -351,16 +351,27 @@ md5_finish(md5_state_t *pms, md5_byte_t digest[16]) digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } -ByteArray MD5::getHash(const ByteArray& data) { - ByteArray digest; - digest.resize(16); +namespace { + template<typename SourceType> + ByteArray getMD5Hash(const SourceType& data) { + ByteArray digest; + digest.resize(16); + + md5_state_t state; + md5_init(&state); + md5_append(&state, reinterpret_cast<const md5_byte_t*>(vecptr(data)), data.size()); + md5_finish(&state, reinterpret_cast<md5_byte_t*>(vecptr(digest))); + + return digest; + } +} - md5_state_t state; - md5_init(&state); - md5_append(&state, reinterpret_cast<const md5_byte_t*>(vecptr(data)), data.size()); - md5_finish(&state, reinterpret_cast<md5_byte_t*>(vecptr(digest))); +ByteArray MD5::getHash(const ByteArray& data) { + return getMD5Hash(data); +} - return digest; +ByteArray MD5::getHash(const SafeByteArray& data) { + return getMD5Hash(data); } } diff --git a/Swiften/StringCodecs/MD5.h b/Swiften/StringCodecs/MD5.h index 93c48e9..b1d610c 100644 --- a/Swiften/StringCodecs/MD5.h +++ b/Swiften/StringCodecs/MD5.h @@ -7,10 +7,12 @@ #pragma once #include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class MD5 { public: static ByteArray getHash(const ByteArray& data); + static ByteArray getHash(const SafeByteArray& data); }; } diff --git a/Swiften/StringCodecs/PBKDF2.cpp b/Swiften/StringCodecs/PBKDF2.cpp index c4a5a7f..81e1208 100644 --- a/Swiften/StringCodecs/PBKDF2.cpp +++ b/Swiften/StringCodecs/PBKDF2.cpp @@ -10,7 +10,7 @@ namespace Swift { -ByteArray PBKDF2::encode(const ByteArray& password, const ByteArray& salt, int iterations) { +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; diff --git a/Swiften/StringCodecs/PBKDF2.h b/Swiften/StringCodecs/PBKDF2.h index dd31921..b1a5986 100644 --- a/Swiften/StringCodecs/PBKDF2.h +++ b/Swiften/StringCodecs/PBKDF2.h @@ -6,11 +6,11 @@ #pragma once -#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class PBKDF2 { public: - static ByteArray encode(const ByteArray& password, const ByteArray& salt, int iterations); + static ByteArray encode(const SafeByteArray& password, const ByteArray& salt, int iterations); }; } diff --git a/Swiften/StringCodecs/SHA1.cpp b/Swiften/StringCodecs/SHA1.cpp index 5001fb2..e4081f4 100644 --- a/Swiften/StringCodecs/SHA1.cpp +++ b/Swiften/StringCodecs/SHA1.cpp @@ -197,11 +197,12 @@ std::vector<unsigned char> SHA1::getHash() const { return digest; } -ByteArray SHA1::getHash(const ByteArray& input) { +template<typename Container> +ByteArray SHA1::getHashInternal(const Container& input) { CTX context; Init(&context); - std::vector<unsigned char> inputCopy(input); + Container inputCopy(input); Update(&context, (boost::uint8_t*) vecptr(inputCopy), inputCopy.size()); ByteArray digest; @@ -211,4 +212,13 @@ ByteArray SHA1::getHash(const ByteArray& input) { return digest; } +ByteArray SHA1::getHash(const ByteArray& input) { + return getHashInternal(input); +} + +ByteArray SHA1::getHash(const SafeByteArray& input) { + return getHashInternal(input); +} + + } diff --git a/Swiften/StringCodecs/SHA1.h b/Swiften/StringCodecs/SHA1.h index 671d890..25bfa54 100644 --- a/Swiften/StringCodecs/SHA1.h +++ b/Swiften/StringCodecs/SHA1.h @@ -10,6 +10,7 @@ #include <boost/cstdint.hpp> #include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> namespace Swift { class SHA1 { @@ -26,6 +27,8 @@ namespace Swift { */ static ByteArray getHash(const ByteArray& data); + static ByteArray getHash(const SafeByteArray& data); + private: typedef struct { boost::uint32_t state[5]; @@ -37,6 +40,8 @@ namespace Swift { static void Update(CTX* context, boost::uint8_t* data, unsigned int len); static void Final(boost::uint8_t digest[20], CTX* context); + template<typename Container> static ByteArray getHashInternal(const Container& input); + private: CTX context; }; diff --git a/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp b/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp index efb613f..1c9d158 100644 --- a/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp +++ b/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp @@ -22,7 +22,7 @@ class HMACSHA1Test : public CppUnit::TestFixture { public: void testGetResult() { - ByteArray result(HMACSHA1::getResult(createByteArray("foo"), createByteArray("foobar"))); + ByteArray result(HMACSHA1::getResult(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); } }; diff --git a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp index ae55ac8..9d91fea 100644 --- a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp +++ b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp @@ -24,19 +24,19 @@ class PBKDF2Test : public CppUnit::TestFixture { public: void testGetResult_I1() { - ByteArray result(PBKDF2::encode(createByteArray("password"), createByteArray("salt"), 1)); + ByteArray result(PBKDF2::encode(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(createByteArray("password"), createByteArray("salt"), 2)); + ByteArray result(PBKDF2::encode(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(createByteArray("password"), createByteArray("salt"), 4096)); + ByteArray result(PBKDF2::encode(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); } |