diff options
Diffstat (limited to 'Swiften/StringCodecs')
24 files changed, 882 insertions, 264 deletions
diff --git a/Swiften/StringCodecs/Base64.cpp b/Swiften/StringCodecs/Base64.cpp index 795d982..e4eaa4e 100644 --- a/Swiften/StringCodecs/Base64.cpp +++ b/Swiften/StringCodecs/Base64.cpp @@ -5,50 +5,63 @@   */  #include <boost/numeric/conversion/cast.hpp> +  #include <algorithm> -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/StringCodecs/Base64.h> +#include <Swiften/Base/Algorithm.h>  namespace Swift {  #pragma GCC diagnostic ignored "-Wold-style-cast" -std::string Base64::encode(const ByteArray &s) { -	int i; -	int len = s.getSize(); -	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); +} + +SafeByteArray Base64::encode(const SafeByteArray &s) { +	return base64Encode<SafeByteArray, SafeByteArray>(s);  }  ByteArray Base64::decode(const std::string& input) {  	std::string inputWithoutNewlines(input); -	inputWithoutNewlines.erase(std::remove(inputWithoutNewlines.begin(), inputWithoutNewlines.end(), '\n'), inputWithoutNewlines.end()); +	erase(inputWithoutNewlines, '\n');  	const std::string& s = inputWithoutNewlines;  	ByteArray p; diff --git a/Swiften/StringCodecs/Base64.h b/Swiften/StringCodecs/Base64.h index 4b19a9f..2d67971 100644 --- a/Swiften/StringCodecs/Base64.h +++ b/Swiften/StringCodecs/Base64.h @@ -9,12 +9,15 @@  #include <vector>  #include <string> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h>  namespace Swift {  	class Base64 {  		public:  			static std::string encode(const ByteArray& s); +			static SafeByteArray encode(const SafeByteArray& s); +  			static ByteArray decode(const std::string &s);  	};  } diff --git a/Swiften/StringCodecs/HMAC.h b/Swiften/StringCodecs/HMAC.h new file mode 100644 index 0000000..cf0abfe --- /dev/null +++ b/Swiften/StringCodecs/HMAC.h @@ -0,0 +1,66 @@ +/* + * 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 { +		template<typename KeyType> struct KeyWrapper; +		template<> struct KeyWrapper<ByteArray> { +			ByteArray wrap(const ByteArray& hash) const { +				return hash; +			} +		}; +		template<> struct KeyWrapper<SafeByteArray> { +			SafeByteArray wrap(const ByteArray& hash) const { +				return createSafeByteArray(hash); +			} +		}; + +		template<typename Hash, typename KeyType, int BlockSize> +		static ByteArray getHMAC(const KeyType& key, const ByteArray& data) { +			Hash hash; + +			// Create the padded key +			KeyType paddedKey(key.size() <= BlockSize ? key : KeyWrapper<KeyType>().wrap(hash(key))); +			paddedKey.resize(BlockSize, 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, int BlockSize> +	class HMAC { +		private: + +		public: +			ByteArray operator()(const ByteArray& key, const ByteArray& data) const { +				return HMAC_Detail::getHMAC<Hash,ByteArray,BlockSize>(key, data); +			} + +			ByteArray operator()(const SafeByteArray& key, const ByteArray& data) const { +				return HMAC_Detail::getHMAC<Hash,SafeByteArray,BlockSize>(key, data); +			} +	}; +} diff --git a/Swiften/StringCodecs/HMACSHA1.cpp b/Swiften/StringCodecs/HMACSHA1.cpp deleted file mode 100644 index 6ae5513..0000000 --- a/Swiften/StringCodecs/HMACSHA1.cpp +++ /dev/null @@ -1,80 +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/ByteArray.h" - -namespace Swift { - -static const unsigned int B = 64; - -ByteArray HMACSHA1::getResult(const ByteArray& key, const ByteArray& data) { -	assert(key.getSize() <= B); - -	// Create the padded key -	ByteArray paddedKey(key); -	paddedKey.resize(B, 0x0); - -	// Create the first value -	ByteArray x(paddedKey); -	for (unsigned int i = 0; i < x.getSize(); ++i) { -		x[i] ^= 0x36; -	} -	x += data; - -	// Create the second value -	ByteArray y(paddedKey); -	for (unsigned int i = 0; i < y.getSize(); ++i) { -		y[i] ^= 0x5c; -	} -	y += SHA1::getHash(x); - -	return SHA1::getHash(y); -} - -#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.getSize(); -	unsigned char* x = (unsigned char*) malloc(xSize * sizeof(unsigned char)); -	memset(x, 0, B); -	memcpy(x, key.getData(), key.getSize()); -	for (unsigned int i = 0; i < (B>>32); ++i) { -		x[i<<32] ^= 0x36363636; -	} -	memcpy(x + B, data.getData(), data.getSize()); - -	// Create the second value -	unsigned char y[B + 20]; -	memset(y, 0, B); -	memcpy(y, key.getData(), key.getSize()); -	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/HMAC_SHA1.h index cc6cb04..8f403c6 100644 --- a/Swiften/StringCodecs/HMACSHA1.h +++ b/Swiften/StringCodecs/HMAC_SHA1.h @@ -6,11 +6,9 @@  #pragma once -namespace Swift { -	class ByteArray; +#include <Swiften/StringCodecs/HMAC.h> +#include <Swiften/StringCodecs/SHA1.h> -	class HMACSHA1 { -		public: -			static ByteArray getResult(const ByteArray& key, const ByteArray& data); -	}; +namespace Swift { +	typedef HMAC<SHA1, 64> HMAC_SHA1;  } diff --git a/Swiften/StringCodecs/HMAC_SHA256.h b/Swiften/StringCodecs/HMAC_SHA256.h new file mode 100644 index 0000000..2d856cb --- /dev/null +++ b/Swiften/StringCodecs/HMAC_SHA256.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/StringCodecs/HMAC.h> +#include <Swiften/StringCodecs/SHA256.h> + +namespace Swift { +	typedef HMAC<SHA256, 64> HMAC_SHA256; +} diff --git a/Swiften/StringCodecs/Hexify.cpp b/Swiften/StringCodecs/Hexify.cpp index 61732b0..367743c 100644 --- a/Swiften/StringCodecs/Hexify.cpp +++ b/Swiften/StringCodecs/Hexify.cpp @@ -4,14 +4,14 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/StringCodecs/Hexify.h" +#include <Swiften/StringCodecs/Hexify.h>  #include <sstream>  #include <iomanip>  #include <boost/numeric/conversion/cast.hpp>  #include <string> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h>  namespace Swift { @@ -25,7 +25,7 @@ std::string Hexify::hexify(const ByteArray& data) {  	std::ostringstream result;  	result << std::hex; -	for (unsigned int i = 0; i < data.getSize(); ++i) { +	for (unsigned int i = 0; i < data.size(); ++i) {  		result << std::setw(2) << std::setfill('0') << boost::numeric_cast<unsigned int>(static_cast<unsigned char>(data[i]));  	}  	return std::string(result.str()); diff --git a/Swiften/StringCodecs/Hexify.h b/Swiften/StringCodecs/Hexify.h index f85db15..9815e21 100644 --- a/Swiften/StringCodecs/Hexify.h +++ b/Swiften/StringCodecs/Hexify.h @@ -6,12 +6,9 @@  #pragma once -#include <string> +#include <Swiften/Base/ByteArray.h>  namespace Swift { -	 -	class ByteArray; -  	class Hexify {  		public:  			static std::string hexify(unsigned char byte); diff --git a/Swiften/StringCodecs/MD5.cpp b/Swiften/StringCodecs/MD5.cpp index 718f52e..0d36254 100644 --- a/Swiften/StringCodecs/MD5.cpp +++ b/Swiften/StringCodecs/MD5.cpp @@ -33,12 +33,13 @@  #pragma GCC diagnostic ignored "-Wold-style-cast" -#include "Swiften/StringCodecs/MD5.h" +#include <Swiften/StringCodecs/MD5.h>  #include <cassert> +#include <string.h> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Base/Platform.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/Platform.h>  namespace Swift { @@ -124,13 +125,13 @@ static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) {  		a = pms->abcd[0], b = pms->abcd[1],  		c = pms->abcd[2], d = pms->abcd[3];  		md5_word_t t; -#ifdef SWIFTEN_BIG_ENDIAN -		/* Define storage only for big-endian CPUs. */ -		md5_word_t X[16]; -#else +#ifdef SWIFTEN_LITTLE_ENDIAN  		/* Define storage for little-endian or both types of CPUs. */  		md5_word_t xbuf[16];  		const md5_word_t *X; +#else +		/* Define storage only for big-endian CPUs. */ +		md5_word_t X[16];  #endif  		{ @@ -350,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*>(data.getData()), data.getSize()); -	md5_finish(&state, reinterpret_cast<md5_byte_t*>(digest.getData())); +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 b896529..b1d610c 100644 --- a/Swiften/StringCodecs/MD5.h +++ b/Swiften/StringCodecs/MD5.h @@ -6,11 +6,13 @@  #pragma once -namespace Swift { -	class ByteArray; +#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 deleted file mode 100644 index a652242..0000000 --- a/Swiften/StringCodecs/PBKDF2.cpp +++ /dev/null @@ -1,26 +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" - -namespace Swift { - -ByteArray PBKDF2::encode(const ByteArray& password, const ByteArray& salt, int iterations) { -	ByteArray u = HMACSHA1::getResult(password, salt + ByteArray("\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.getSize(); ++j) { -			result[j] ^= u[j]; -		} -		++i; -	} -	return result; -} - -} diff --git a/Swiften/StringCodecs/PBKDF2.h b/Swiften/StringCodecs/PBKDF2.h index 7f87af7..0c04145 100644 --- a/Swiften/StringCodecs/PBKDF2.h +++ b/Swiften/StringCodecs/PBKDF2.h @@ -6,11 +6,26 @@  #pragma once -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/SafeByteArray.h> +#include <Swiften/Base/Concat.h>  namespace Swift {  	class PBKDF2 {  		public: -			static ByteArray encode(const ByteArray& 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.cpp b/Swiften/StringCodecs/SHA1.cpp index 9882f70..e4081f4 100644 --- a/Swiften/StringCodecs/SHA1.cpp +++ b/Swiften/StringCodecs/SHA1.cpp @@ -4,10 +4,14 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Base/Platform.h" +#include <Swiften/StringCodecs/SHA1.h> + +#include <Swiften/Base/Platform.h>  #pragma GCC diagnostic ignored "-Wold-style-cast" +using namespace Swift; +  /*  SHA-1 in C  By Steve Reid <steve@edmweb.com> @@ -25,21 +29,9 @@ A million repetitions of "a"  /* #define LITTLE_ENDIAN * This should be #define'd if true. */  /* #define SHA1HANDSOFF * Copies data before messing with it. */ -#include <boost/cstdint.hpp>  #include <stdio.h>  #include <string.h> -typedef struct { -		boost::uint32_t state[5]; -		boost::uint32_t count[2]; -		boost::uint8_t buffer[64]; -} SHA1_CTX; - -void SHA1Transform(boost::uint32_t state[5], boost::uint8_t buffer[64]); -void SHA1Init(SHA1_CTX* context); -void SHA1Update(SHA1_CTX* context, boost::uint8_t* data, unsigned int len); -void SHA1Final(boost::uint8_t digest[20], SHA1_CTX* context); -  #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))  /* blk0() and blk() perform the initial expand. */ @@ -63,7 +55,7 @@ void SHA1Final(boost::uint8_t digest[20], SHA1_CTX* context);  /* Hash a single 512-bit block. This is the core of the algorithm. */ -void SHA1Transform(boost::uint32_t state[5], boost::uint8_t buffer[64]) +void SHA1::Transform(boost::uint32_t state[5], boost::uint8_t buffer[64])  {  boost::uint32_t a, b, c, d, e;  typedef union { @@ -118,7 +110,7 @@ static boost::uint8_t workspace[64];  /* SHA1Init - Initialize new context */ -void SHA1Init(SHA1_CTX* context) +void SHA1::Init(SHA1::CTX* context)  {  		/* SHA1 initialization constants */  		context->state[0] = 0x67452301; @@ -132,7 +124,7 @@ void SHA1Init(SHA1_CTX* context)  /* Run your data through this. */ -void SHA1Update(SHA1_CTX* context, boost::uint8_t* data, unsigned int len) +void SHA1::Update(SHA1::CTX* context, boost::uint8_t* data, unsigned int len)  {  unsigned int i, j; @@ -141,9 +133,9 @@ unsigned int i, j;  		context->count[1] += (len >> 29);  		if ((j + len) > 63) {  				memcpy(&context->buffer[j], data, (i = 64-j)); -				SHA1Transform(context->state, context->buffer); +				Transform(context->state, context->buffer);  				for ( ; i + 63 < len; i += 64) { -						SHA1Transform(context->state, &data[i]); +						Transform(context->state, &data[i]);  				}  				j = 0;  		} @@ -154,7 +146,7 @@ unsigned int i, j;  /* Add padding and return the message digest. */ -void SHA1Final(boost::uint8_t digest[20], SHA1_CTX* context) +void SHA1::Final(boost::uint8_t digest[20], SHA1::CTX* context)  {  boost::uint32_t i, j;  boost::uint8_t finalcount[8]; @@ -163,11 +155,11 @@ boost::uint8_t finalcount[8];  				finalcount[i] = (boost::uint8_t) ((context->count[(i >= 4 ? 0 : 1)]  				 >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */  		} -		SHA1Update(context, (boost::uint8_t *)("\200"), 1); +		Update(context, (boost::uint8_t *)("\200"), 1);  		while ((context->count[0] & 504) != 448) { -				SHA1Update(context, (boost::uint8_t *)("\0"), 1); +				Update(context, (boost::uint8_t *)("\0"), 1);  		} -		SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */ +		Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */  		for (i = 0; i < 20; i++) {  				digest[i] = (boost::uint8_t)  				 ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); @@ -179,25 +171,54 @@ boost::uint8_t finalcount[8];  		memset(context->count, 0, 8);  		memset(&finalcount, 0, 8);  #ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */ -		SHA1Transform(context->state, context->buffer); +		Transform(context->state, context->buffer);  #endif  }  // ----------------------------------------------------------------------------- -#include "Swiften/StringCodecs/SHA1.h" -  namespace Swift { -ByteArray SHA1::getHash(const ByteArray& input) { -	ByteArray inputCopy(input); +SHA1::SHA1() { +	Init(&context); +} + +SHA1& SHA1::update(const std::vector<unsigned char>& input) { +	std::vector<unsigned char> inputCopy(input); +	Update(&context, (boost::uint8_t*) vecptr(inputCopy), inputCopy.size()); +	return *this; +} + +std::vector<unsigned char> SHA1::getHash() const { +	std::vector<unsigned char> digest; +	digest.resize(20); +	CTX contextCopy(context); +	Final((boost::uint8_t*) vecptr(digest), &contextCopy); +	return digest; +} + +template<typename Container> +ByteArray SHA1::getHashInternal(const Container& input) { +	CTX context; +	Init(&context); + +	Container inputCopy(input); +	Update(&context, (boost::uint8_t*) vecptr(inputCopy), inputCopy.size()); +  	ByteArray digest;  	digest.resize(20); -	SHA1_CTX context; -	SHA1Init(&context); -	SHA1Update(&context, (boost::uint8_t*) inputCopy.getData(), inputCopy.getSize()); -	SHA1Final((boost::uint8_t*) digest.getData(), &context); +	Final((boost::uint8_t*) vecptr(digest), &context); +  	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 fc5ba0e..19488cb 100644 --- a/Swiften/StringCodecs/SHA1.h +++ b/Swiften/StringCodecs/SHA1.h @@ -6,11 +6,50 @@  #pragma once -#include "Swiften/Base/ByteArray.h" +#include <vector> +#include <boost/cstdint.hpp> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h>  namespace Swift {  	class SHA1 {  		public: +			SHA1(); + +			SHA1& update(const std::vector<unsigned char>& data); +			std::vector<unsigned char> getHash() const; + +			/** +			 * Equivalent of: +			 *	SHA1().update(data),getHash(), but slightly more efficient and +			 *	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]; +					boost::uint32_t count[2]; +					boost::uint8_t buffer[64]; +			} CTX; +			static void Init(CTX* context); +			static void Transform(boost::uint32_t state[5], boost::uint8_t buffer[64]); +			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/SHA256.cpp b/Swiften/StringCodecs/SHA256.cpp new file mode 100644 index 0000000..f92e7af --- /dev/null +++ b/Swiften/StringCodecs/SHA256.cpp @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/StringCodecs/SHA256.h> + +#include <cassert> +#include <algorithm> +#include <string.h> + +#pragma GCC diagnostic ignored "-Wold-style-cast" + +using namespace Swift; + +// Copied & adapted from LibTomCrypt, by Tom St Denis, tomstdenis@gmail.com, http://libtom.org +// Substituted some macros by the platform-independent (slower) variants + +#include <stdlib.h> + +#define CRYPT_OK 0 +#define CRYPT_INVALID_ARG -1 +#define LTC_ARGCHK assert + +#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) + +#define LOAD32H(x, y)														 \ +		 { x = ((unsigned long)((y)[0] & 255)<<24) | \ +					 ((unsigned long)((y)[1] & 255)<<16) | \ +					 ((unsigned long)((y)[2] & 255)<<8)  | \ +					 ((unsigned long)((y)[3] & 255)); } + +#define STORE32H(x, y)																																		 \ +		 { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255);	 \ +			 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define STORE64H(x, y)																																		 \ +	 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);		 \ +		 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);		 \ +		 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);		 \ +		 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +/* a simple macro for making hash "process" functions */ +#define HASH_PROCESS(func_name, compress_name, state_var, block_size)												\ +int func_name (State * md, const unsigned char *in, unsigned int inlen)								\ +{																																														\ +		unsigned long n;																																				\ +		int						err;																																			\ +		LTC_ARGCHK(md != NULL);																																	\ +		LTC_ARGCHK(in != NULL || inlen == 0);																																	\ +		if (md-> curlen > sizeof(md->buf)) {														 \ +			 return CRYPT_INVALID_ARG;																														\ +		}																																												\ +		while (inlen > 0) {																																			\ +				if (md->curlen == 0 && inlen >= block_size) {														\ +					 if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) {								\ +							return err;																																		\ +					 }																																								\ +					 md-> length += block_size * 8;																				 \ +					 in							+= block_size;																										\ +					 inlen					-= block_size;																										\ +				} else {																																						\ +					 n = std::min(inlen, (block_size - md-> curlen));														\ +					 memcpy(md-> buf + md-> curlen, in, (size_t)n);							 \ +					 md-> curlen += n;																										 \ +					 in							+= n;																															\ +					 inlen					-= n;																															\ +					 if (md-> curlen == block_size) {																			 \ +							if ((err = compress_name (md, md-> buf)) != CRYPT_OK) {						 \ +								 return err;																																\ +							}																																							\ +							md-> length += 8*block_size;																			 \ +							md-> curlen = 0;																									 \ +					 }																																								\ +			 }																																										\ +		}																																												\ +		return CRYPT_OK;																																				\ +} + +#ifdef LTC_SMALL_CODE +/* the K array */ +static const boost::uint32_t K[64] = { +		0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, +		0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, +		0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, +		0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, +		0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, +		0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, +		0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, +		0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, +		0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, +		0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, +		0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, +		0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, +		0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; +#endif + +/* Various logical functions */ +#define Ch(x,y,z)				(z ^ (x & (y ^ z))) +#define Maj(x,y,z)			(((x | y) & z) | (x & y))  +#define S(x, n)					RORc((x),(n)) +#define R(x, n)					(((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x)				(S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x)				(S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x)				(S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x)				(S(x, 17) ^ S(x, 19) ^ R(x, 10)) + +#ifdef LTC_CLEAN_STACK +int SHA256::_compress(State * md, unsigned char *buf) +#else +int  SHA256::compress(State * md, unsigned char *buf) +#endif +{ +		boost::uint32_t S[8], W[64], t0, t1; +#ifdef LTC_SMALL_CODE +		boost::uint32_t t; +#endif +		int i; + +		/* copy state into S */ +		for (i = 0; i < 8; i++) { +				S[i] = md->state[i]; +		} + +		/* copy the state into 512-bits into W[0..15] */ +		for (i = 0; i < 16; i++) { +				LOAD32H(W[i], buf + (4*i)); +		} + +		/* fill W[16..63] */ +		for (i = 16; i < 64; i++) { +				W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; +		}				  + +		/* Compress */ +#ifdef LTC_SMALL_CODE		 +#define RND(a,b,c,d,e,f,g,h,i)												 \ +		 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];	 \ +		 t1 = Sigma0(a) + Maj(a, b, c);										 \ +		 d += t0;																					 \ +		 h	= t0 + t1; + +		 for (i = 0; i < 64; ++i) { +				 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); +				 t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];  +				 S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; +		 }	 +#else  +#define RND(a,b,c,d,e,f,g,h,i,ki)										 \ +		 t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i];	 \ +		 t1 = Sigma0(a) + Maj(a, b, c);									 \ +		 d += t0;																				 \ +		 h	= t0 + t1; + +		RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); +		RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); +		RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); +		RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); +		RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); +		RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); +		RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); +		RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); +		RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); +		RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); +		RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); +		RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); +		RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); +		RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); +		RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); +		RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); +		RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); +		RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); +		RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); +		RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); +		RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); +		RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); +		RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); +		RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); +		RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); +		RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); +		RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); +		RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); +		RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); +		RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); +		RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); +		RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); +		RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); +		RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); +		RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); +		RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); +		RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); +		RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); +		RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); +		RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); +		RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); +		RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); +		RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); +		RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); +		RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); +		RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); +		RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); +		RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); +		RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); +		RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); +		RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); +		RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); +		RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); +		RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); +		RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); +		RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); +		RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); +		RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); +		RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); +		RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); +		RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); +		RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); +		RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); +		RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); + +#undef RND		  +		 +#endif		  + +		/* feedback */ +		for (i = 0; i < 8; i++) { +				md->state[i] = md->state[i] + S[i]; +		} +		return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int SHA256::compress(State * md, unsigned char *buf) +{ +		int err; +		err = SHA256::_compress(md, buf); +		burn_stack(sizeof(boost::uint32_t) * 74); +		return err; +} +#endif + +/** +	 Initialize the hash state +	 @param md	 The hash state you wish to initialize +	 @return CRYPT_OK if successful +*/ +int SHA256::init(State * md) +{ +		LTC_ARGCHK(md != NULL); + +		md->curlen = 0; +		md->length = 0; +		md->state[0] = 0x6A09E667UL; +		md->state[1] = 0xBB67AE85UL; +		md->state[2] = 0x3C6EF372UL; +		md->state[3] = 0xA54FF53AUL; +		md->state[4] = 0x510E527FUL; +		md->state[5] = 0x9B05688CUL; +		md->state[6] = 0x1F83D9ABUL; +		md->state[7] = 0x5BE0CD19UL; +		return CRYPT_OK; +} + +/** +	 Process a block of memory though the hash +	 @param md		 The hash state +	 @param in		 The data to hash +	 @param inlen  The length of the data (octets) +	 @return CRYPT_OK if successful +*/ +HASH_PROCESS(SHA256::process, SHA256::compress, sha256, 64) + +/** +	 Terminate the hash to get the digest +	 @param md	The hash state +	 @param out [out] The destination of the hash (32 bytes) +	 @return CRYPT_OK if successful +*/ +int SHA256::done(State * md, unsigned char *out) +{ +		int i; + +		LTC_ARGCHK(md  != NULL); +		LTC_ARGCHK(out != NULL); + +		if (md->curlen >= sizeof(md->buf)) { +			 return CRYPT_INVALID_ARG; +		} + + +		/* increase the length of the message */ +		md->length += md->curlen * 8; + +		/* append the '1' bit */ +		md->buf[md->curlen++] = (unsigned char)0x80; + +		/* if the length is currently above 56 bytes we append zeros +		 * then compress.  Then we can fall back to padding zeros and length +		 * encoding like normal. +		 */ +		if (md->curlen > 56) { +				while (md->curlen < 64) { +						md->buf[md->curlen++] = (unsigned char)0; +				} +				SHA256::compress(md, md->buf); +				md->curlen = 0; +		} + +		/* pad upto 56 bytes of zeroes */ +		while (md->curlen < 56) { +				md->buf[md->curlen++] = (unsigned char)0; +		} + +		/* store length */ +		STORE64H(md->length, md->buf+56); +		SHA256::compress(md, md->buf); + +		/* copy output */ +		for (i = 0; i < 8; i++) { +				STORE32H(md->state[i], out+(4*i)); +		} +#ifdef LTC_CLEAN_STACK +		zeromem(md, sizeof(State)); +#endif +		return CRYPT_OK; +} + +// End copied code + +namespace Swift { + +SHA256::SHA256() { +	init(&state); +} + +SHA256& SHA256::update(const std::vector<unsigned char>& input) { +	std::vector<unsigned char> inputCopy(input); +	process(&state, (boost::uint8_t*) vecptr(inputCopy), inputCopy.size()); +	return *this; +} + +std::vector<unsigned char> SHA256::getHash() const { +	std::vector<unsigned char> digest; +	digest.resize(256/8); +	State contextCopy(state); +	done(&contextCopy, (boost::uint8_t*) vecptr(digest)); +	return digest; +} + +template<typename Container> +ByteArray SHA256::getHashInternal(const Container& input) { +	State context; +	init(&context); + +	Container inputCopy(input); +	process(&context, (boost::uint8_t*) vecptr(inputCopy), inputCopy.size()); + +	ByteArray digest; +	digest.resize(256/8); +	done(&context, (boost::uint8_t*) vecptr(digest)); + +	return digest; +} + +ByteArray SHA256::getHash(const ByteArray& input) { +	return getHashInternal(input); +} + +ByteArray SHA256::getHash(const SafeByteArray& input) { +	return getHashInternal(input); +} + +} diff --git a/Swiften/StringCodecs/SHA256.h b/Swiften/StringCodecs/SHA256.h new file mode 100644 index 0000000..28a0e05 --- /dev/null +++ b/Swiften/StringCodecs/SHA256.h @@ -0,0 +1,56 @@ +/* + * 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 <vector> +#include <boost/cstdint.hpp> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Base/SafeByteArray.h> + +namespace Swift { +	class SHA256 { +		public: +			SHA256(); + +			SHA256& update(const std::vector<unsigned char>& data); +			std::vector<unsigned char> getHash() const; + +			/** +			 * Equivalent of: +			 *	SHA256().update(data),getHash(), but slightly more efficient and +			 *	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: +			struct State { +					boost::uint64_t length; +					boost::uint32_t state[8], curlen; +					unsigned char buf[64]; +			}; + +			static int init(State *md); +			static int process(State * md, const unsigned char *in, unsigned int inlen); +			static int compress(State *md, unsigned char *buf); +			static int done(State * md, unsigned char *out); + +			template<typename Container> static	ByteArray getHashInternal(const Container& input); + +		private: +			State state; +	}; +} diff --git a/Swiften/StringCodecs/UnitTest/Base64Test.cpp b/Swiften/StringCodecs/UnitTest/Base64Test.cpp index b263050..f6a424b 100644 --- a/Swiften/StringCodecs/UnitTest/Base64Test.cpp +++ b/Swiften/StringCodecs/UnitTest/Base64Test.cpp @@ -4,12 +4,13 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h>  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/StringCodecs/Base64.h" +#include <Swiften/StringCodecs/Base64.h>  using namespace Swift; @@ -24,12 +25,12 @@ class Base64Test : public CppUnit::TestFixture {  	public:  		void testEncode() { -			std::string result(Base64::encode("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890")); +			std::string result(Base64::encode(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890")));  			CPPUNIT_ASSERT_EQUAL(std::string("QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejEyMzQ1Njc4OTA="), result);  		}  		void testEncode_NonAscii() { -			std::string result(Base64::encode(ByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"))); +			std::string result(Base64::encode(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed")));  			CPPUNIT_ASSERT_EQUAL(std::string("QgayPKawpkPSDYmwT/WM94uAlu0="), result);  		} @@ -40,7 +41,7 @@ class Base64Test : public CppUnit::TestFixture {  		void testDecode() {  			ByteArray result(Base64::decode("QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejEyMzQ1Njc4OTA=")); -			CPPUNIT_ASSERT_EQUAL(ByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"), result); +			CPPUNIT_ASSERT_EQUAL(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"), result);  		}  		void testDecode_NoData() { diff --git a/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp b/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp deleted file mode 100644 index 44bd5b7..0000000 --- a/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp +++ /dev/null @@ -1,29 +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/Base/ByteArray.h" - -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/extensions/TestFactoryRegistry.h> - -#include "Swiften/Base/ByteArray.h" -#include "Swiften/StringCodecs/HMACSHA1.h" - -using namespace Swift; - -class HMACSHA1Test : public CppUnit::TestFixture { -		CPPUNIT_TEST_SUITE(HMACSHA1Test); -		CPPUNIT_TEST(testGetResult); -		CPPUNIT_TEST_SUITE_END(); - -	public: -		void testGetResult() { -			ByteArray result(HMACSHA1::getResult("foo", "foobar")); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\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); diff --git a/Swiften/StringCodecs/UnitTest/HMACTest.cpp b/Swiften/StringCodecs/UnitTest/HMACTest.cpp new file mode 100644 index 0000000..50b1330 --- /dev/null +++ b/Swiften/StringCodecs/UnitTest/HMACTest.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Base/ByteArray.h> +#include <Swiften/StringCodecs/HMAC_SHA1.h> +#include <Swiften/StringCodecs/HMAC_SHA256.h> + +using namespace Swift; + +class HMACTest : public CppUnit::TestFixture { +		CPPUNIT_TEST_SUITE(HMACTest); +		CPPUNIT_TEST(testGetResult); +		CPPUNIT_TEST(testGetResult_KeyLongerThanBlockSize); +		CPPUNIT_TEST(testGetResult_RFC4231_1); +		CPPUNIT_TEST(testGetResult_RFC4231_7); +		CPPUNIT_TEST_SUITE_END(); + +	public: +		void testGetResult() { +			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); +		} + +		void testGetResult_KeyLongerThanBlockSize() { +			ByteArray result(HMAC_SHA1()(createSafeByteArray("---------|---------|---------|---------|---------|----------|---------|"), createByteArray("foobar"))); +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xd6""n""\x8f""P|1""\xd3"",""\x6"" ""\xb9\xe3""gg""\x8e\xcf"" ]+""\xa"), result); +		} + +		void testGetResult_RFC4231_1() { +			ByteArray result(HMAC_SHA256()(createSafeByteArray("\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20), createByteArray("Hi There"))); +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7", 32), result); +		} + +		void testGetResult_RFC4231_7() { +			ByteArray result(HMAC_SHA256()(createSafeByteArray("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131), createByteArray("This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."))); +			CPPUNIT_ASSERT_EQUAL(createByteArray("\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2", 32), result); +		} +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(HMACTest); diff --git a/Swiften/StringCodecs/UnitTest/HexifyTest.cpp b/Swiften/StringCodecs/UnitTest/HexifyTest.cpp index 0f267bf..9cbd0d4 100644 --- a/Swiften/StringCodecs/UnitTest/HexifyTest.cpp +++ b/Swiften/StringCodecs/UnitTest/HexifyTest.cpp @@ -7,9 +7,9 @@  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/StringCodecs/Hexify.h" +#include <Swiften/StringCodecs/Hexify.h>  #include <string> -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h>  using namespace Swift; @@ -21,7 +21,7 @@ class HexifyTest : public CppUnit::TestFixture {  	public:  		void testHexify() { -			CPPUNIT_ASSERT_EQUAL(std::string("4206b23ca6b0a643d20d89b04ff58cf78b8096ed"), Hexify::hexify(ByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"))); +			CPPUNIT_ASSERT_EQUAL(std::string("4206b23ca6b0a643d20d89b04ff58cf78b8096ed"), Hexify::hexify(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed")));  		}  		void testHexify_Byte() { diff --git a/Swiften/StringCodecs/UnitTest/MD5Test.cpp b/Swiften/StringCodecs/UnitTest/MD5Test.cpp index b76af48..ce7e422 100644 --- a/Swiften/StringCodecs/UnitTest/MD5Test.cpp +++ b/Swiften/StringCodecs/UnitTest/MD5Test.cpp @@ -4,13 +4,14 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h>  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/StringCodecs/MD5.h" -#include "Swiften/Base/ByteArray.h" +#include <Swiften/StringCodecs/MD5.h> +#include <Swiften/Base/ByteArray.h>  using namespace Swift; @@ -22,15 +23,15 @@ class MD5Test : public CppUnit::TestFixture {  	public:  		void testGetHash_Empty() { -			ByteArray result(MD5::getHash("")); +			ByteArray result(MD5::getHash(createByteArray(""))); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", 16), result); +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", 16), result);  		}  		void testGetHash_Alphabet() { -			ByteArray result(MD5::getHash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")); +			ByteArray result(MD5::getHash(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"))); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result); +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result);  		}  }; diff --git a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp index 092fe31..608ca62 100644 --- a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp +++ b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp @@ -4,13 +4,15 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h>  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/StringCodecs/PBKDF2.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/StringCodecs/PBKDF2.h> +#include <Swiften/StringCodecs/HMAC_SHA1.h>  using namespace Swift; @@ -23,21 +25,21 @@ class PBKDF2Test : public CppUnit::TestFixture {  	public:  		void testGetResult_I1() { -			ByteArray result(PBKDF2::encode("password", "salt", 1)); +			ByteArray result(PBKDF2::encode<HMAC_SHA1 >(createSafeByteArray("password"), createByteArray("salt"), 1)); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6"), result); +			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("password", "salt", 2)); +			ByteArray result(PBKDF2::encode<HMAC_SHA1 >(createSafeByteArray("password"), createByteArray("salt"), 2)); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\xea\x6c\x1\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57"), result); +			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("password", "salt", 4096)); +			ByteArray result(PBKDF2::encode<HMAC_SHA1 >(createSafeByteArray("password"), createByteArray("salt"), 4096)); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\x4b\x00\x79\x1\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1", 20), result); +			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);  		}  }; diff --git a/Swiften/StringCodecs/UnitTest/SHA1Test.cpp b/Swiften/StringCodecs/UnitTest/SHA1Test.cpp index 9434235..bdccb1c 100644 --- a/Swiften/StringCodecs/UnitTest/SHA1Test.cpp +++ b/Swiften/StringCodecs/UnitTest/SHA1Test.cpp @@ -4,41 +4,89 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Base/ByteArray.h" +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h>  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/StringCodecs/SHA1.h" +#include <Swiften/StringCodecs/SHA1.h>  using namespace Swift;  class SHA1Test : public CppUnit::TestFixture {  		CPPUNIT_TEST_SUITE(SHA1Test);  		CPPUNIT_TEST(testGetHash); -		CPPUNIT_TEST(testGetHash_Twice); +		CPPUNIT_TEST(testGetHash_TwoUpdates); +		CPPUNIT_TEST(testGetHash_TwoGetHash);  		CPPUNIT_TEST(testGetHash_NoData); +		CPPUNIT_TEST(testGetHash_InterleavedUpdate); +		CPPUNIT_TEST(testGetHashStatic); +		CPPUNIT_TEST(testGetHashStatic_Twice); +		CPPUNIT_TEST(testGetHashStatic_NoData);  		CPPUNIT_TEST_SUITE_END();  	public:  		void testGetHash() { -			ByteArray result(SHA1::getHash("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result); +			SHA1 sha; +			sha.update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); + +			CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha.getHash()); +		} + +		void testGetHash_TwoUpdates() { +			SHA1 sha; +			sha.update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<")); +			sha.update(createByteArray("http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); + +			CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha.getHash()); +		} + +		void testGetHash_TwoGetHash() { +			SHA1 sha; +			sha.update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); + +			sha.getHash(); + +			CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha.getHash()); +		} + +		void testGetHash_InterleavedUpdate() { +			SHA1 sha; + +			sha.update(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<")); +			sha.getHash(); +			sha.update(createByteArray("http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<")); + +			CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), sha.getHash()); +		} + + +		void testGetHash_NoData() { +			SHA1 sha; +			sha.update(std::vector<unsigned char>()); + +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09"), sha.getHash());  		} +		void testGetHashStatic() { +			ByteArray result(SHA1::getHash(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<"))); +			CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result); +		} -		void testGetHash_Twice() { -			ByteArray input("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<"); + +		void testGetHashStatic_Twice() { +			ByteArray input(createByteArray("client/pc//Exodus 0.9.1<http://jabber.org/protocol/caps<http://jabber.org/protocol/disco#info<http://jabber.org/protocol/disco#items<http://jabber.org/protocol/muc<"));  			SHA1::getHash(input);  			ByteArray result(SHA1::getHash(input)); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result); +			CPPUNIT_ASSERT_EQUAL(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result);  		} -		void testGetHash_NoData() { +		void testGetHashStatic_NoData() {  			ByteArray result(SHA1::getHash(ByteArray())); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09"), result); +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09"), result);  		}  }; diff --git a/Swiften/StringCodecs/UnitTest/SHA256Test.cpp b/Swiften/StringCodecs/UnitTest/SHA256Test.cpp new file mode 100644 index 0000000..5bcdd11 --- /dev/null +++ b/Swiften/StringCodecs/UnitTest/SHA256Test.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Base/ByteArray.h> +#include <QA/Checker/IO.h> + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/StringCodecs/SHA256.h> + +using namespace Swift; + +class SHA256Test : public CppUnit::TestFixture { +		CPPUNIT_TEST_SUITE(SHA256Test); +		CPPUNIT_TEST(testGetHashStatic_Empty); +		CPPUNIT_TEST(testGetHashStatic_Small); +		CPPUNIT_TEST(testGetHashStatic_Large); +		CPPUNIT_TEST_SUITE_END(); + +	public: +		void testGetHashStatic_Empty() { +			ByteArray result(SHA256::getHash(createByteArray(""))); +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xe3\xb0\xc4" "B" "\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99" "o" "\xb9" "$'" "\xae" "A" "\xe4" "d" "\x9b\x93" "L" "\xa4\x95\x99\x1b" "xR" "\xb8" "U", 32), result); +		} + +		void testGetHashStatic_Small() { +			ByteArray result(SHA256::getHash(createByteArray("abc"))); +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad", 32), result); +		} + +		void testGetHashStatic_Large() { +			ByteArray result(SHA256::getHash(createByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"))); +			CPPUNIT_ASSERT_EQUAL(createByteArray("\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1", 32), result); +		} +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(SHA256Test);  | 
 Swift