diff options
117 files changed, 1522 insertions, 1831 deletions
| diff --git a/COPYING.thirdparty b/COPYING.thirdparty index 1ab927d..aeaf066 100644 --- a/COPYING.thirdparty +++ b/COPYING.thirdparty @@ -756,48 +756,3 @@ necessary.  Here is a sample; alter the names:    Ty Coon, President of Vice  That's all there is to it! - - -=========== -LibTomCrypt -=========== - -Swiften contains adapted code from LibTomCrypt by Tom St Denis -LibTomCrypt is free for all purposes under the public domain. - - -=== -MD5 -=== - -Swiften contains adapted code from L. Peter Deutsch's -MD5 implementation. Original license below. - -Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved. - -This software is provided 'as-is', without any express or implied -warranty.  In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not -	 claim that you wrote the original software. If you use this software -	 in a product, an acknowledgment in the product documentation would be -	 appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be -	 misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. - -L. Peter Deutsch -ghost@aladdin.com - - -===== -SHA-1 -===== - -Swiften contains adapted code from Steve Reid's SHA-1 implementation in C. -This code is in the public domain.
\ No newline at end of file diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index 32d045d..ac0fee4 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -67,7 +67,6 @@  #include "Swiften/Disco/GetDiscoInfoRequest.h"  #include "Swiften/Disco/ClientDiscoManager.h"  #include "Swiften/VCards/GetVCardRequest.h" -#include "Swiften/StringCodecs/SHA1.h"  #include "Swiften/StringCodecs/Hexify.h"  #include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"  #include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h" @@ -89,6 +88,7 @@  #include <Swift/Controllers/HighlightEditorController.h>  #include <Swiften/Client/ClientBlockListManager.h>  #include <Swift/Controllers/BlockListController.h> +#include <Swiften/Crypto/CryptoProvider.h>  namespace Swift { @@ -747,7 +747,7 @@ void MainController::handleVCardReceived(const JID& jid, VCard::ref vCard) {  	if (!jid.equals(jid_, JID::WithoutResource) || !vCard || vCard->getPhoto().empty()) {  		return;  	} -	std::string hash = Hexify::hexify(SHA1::getHash(vCard->getPhoto())); +	std::string hash = Hexify::hexify(networkFactories_->getCryptoProvider()->getSHA1Hash(vCard->getPhoto()));  	if (hash != vCardPhotoHash_) {  		vCardPhotoHash_ = hash;  		if (client_ && client_->isAvailable()) { diff --git a/Swift/Controllers/Storages/AvatarFileStorage.cpp b/Swift/Controllers/Storages/AvatarFileStorage.cpp index b39e586..792b77b 100644 --- a/Swift/Controllers/Storages/AvatarFileStorage.cpp +++ b/Swift/Controllers/Storages/AvatarFileStorage.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -12,12 +12,12 @@  #include <Swiften/Base/foreach.h>  #include <Swiften/Base/String.h> -#include <Swiften/StringCodecs/SHA1.h>  #include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/Crypto/CryptoProvider.h>  namespace Swift { -AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile) : avatarsDir(avatarsDir), avatarsFile(avatarsFile) { +AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile, CryptoProvider* crypto) : avatarsDir(avatarsDir), avatarsFile(avatarsFile), crypto(crypto) {  	if (boost::filesystem::exists(avatarsFile)) {  		try {  			boost::filesystem::ifstream file(avatarsFile); @@ -47,7 +47,7 @@ bool AvatarFileStorage::hasAvatar(const std::string& hash) const {  }  void AvatarFileStorage::addAvatar(const std::string& hash, const ByteArray& avatar) { -	assert(Hexify::hexify(SHA1::getHash(avatar)) == hash); +	assert(Hexify::hexify(crypto->getSHA1Hash(avatar)) == hash);  	boost::filesystem::path avatarPath = getAvatarPath(hash);  	if (!boost::filesystem::exists(avatarPath.parent_path())) { diff --git a/Swift/Controllers/Storages/AvatarFileStorage.h b/Swift/Controllers/Storages/AvatarFileStorage.h index b7e73f5..85a6463 100644 --- a/Swift/Controllers/Storages/AvatarFileStorage.h +++ b/Swift/Controllers/Storages/AvatarFileStorage.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -15,9 +15,11 @@  #include "Swiften/Avatars/AvatarStorage.h"  namespace Swift { +	class CryptoProvider; +  	class AvatarFileStorage : public AvatarStorage {  		public: -			AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile); +			AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile, CryptoProvider* crypto);  			virtual bool hasAvatar(const std::string& hash) const;  			virtual void addAvatar(const std::string& hash, const ByteArray& avatar); @@ -34,6 +36,7 @@ namespace Swift {  		private:  			boost::filesystem::path avatarsDir;  			boost::filesystem::path avatarsFile; +			CryptoProvider* crypto;  			typedef std::map<JID, std::string> JIDAvatarMap;  			JIDAvatarMap jidAvatars;  	}; diff --git a/Swift/Controllers/Storages/CertificateFileStorage.cpp b/Swift/Controllers/Storages/CertificateFileStorage.cpp index 55016d5..b5e85d2 100644 --- a/Swift/Controllers/Storages/CertificateFileStorage.cpp +++ b/Swift/Controllers/Storages/CertificateFileStorage.cpp @@ -10,14 +10,14 @@  #include <boost/filesystem/fstream.hpp>  #include <boost/numeric/conversion/cast.hpp> -#include <Swiften/StringCodecs/SHA1.h>  #include <Swiften/StringCodecs/Hexify.h>  #include <Swiften/TLS/CertificateFactory.h>  #include <Swiften/Base/Log.h> +#include <Swiften/Crypto/CryptoProvider.h>  namespace Swift { -CertificateFileStorage::CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory) : path(path), certificateFactory(certificateFactory) { +CertificateFileStorage::CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory, CryptoProvider* crypto) : path(path), certificateFactory(certificateFactory), crypto(crypto) {  }  bool CertificateFileStorage::hasCertificate(Certificate::ref certificate) const { @@ -56,7 +56,7 @@ void CertificateFileStorage::addCertificate(Certificate::ref certificate) {  }  boost::filesystem::path CertificateFileStorage::getCertificatePath(Certificate::ref certificate) const { -	return path / Hexify::hexify(SHA1::getHash(certificate->toDER())); +	return path / Hexify::hexify(crypto->getSHA1Hash(certificate->toDER()));  }  } diff --git a/Swift/Controllers/Storages/CertificateFileStorage.h b/Swift/Controllers/Storages/CertificateFileStorage.h index f7a60b9..12151d0 100644 --- a/Swift/Controllers/Storages/CertificateFileStorage.h +++ b/Swift/Controllers/Storages/CertificateFileStorage.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -12,10 +12,11 @@  namespace Swift {  	class CertificateFactory; +	class CryptoProvider;  	class CertificateFileStorage : public CertificateStorage {  		public: -			CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory); +			CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory, CryptoProvider* crypto);  			virtual bool hasCertificate(Certificate::ref certificate) const;  			virtual void addCertificate(Certificate::ref certificate); @@ -26,6 +27,7 @@ namespace Swift {  		private:  			boost::filesystem::path path;  			CertificateFactory* certificateFactory; +			CryptoProvider* crypto;  	};  } diff --git a/Swift/Controllers/Storages/CertificateFileStorageFactory.h b/Swift/Controllers/Storages/CertificateFileStorageFactory.h index b215165..6834619 100644 --- a/Swift/Controllers/Storages/CertificateFileStorageFactory.h +++ b/Swift/Controllers/Storages/CertificateFileStorageFactory.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -11,18 +11,20 @@  namespace Swift {  	class CertificateFactory; +	class CryptoProvider;  	class CertificateFileStorageFactory : public CertificateStorageFactory {  		public: -			CertificateFileStorageFactory(const boost::filesystem::path& basePath, CertificateFactory* certificateFactory) : basePath(basePath), certificateFactory(certificateFactory) {} +			CertificateFileStorageFactory(const boost::filesystem::path& basePath, CertificateFactory* certificateFactory, CryptoProvider* crypto) : basePath(basePath), certificateFactory(certificateFactory), crypto(crypto) {}  			virtual CertificateStorage* createCertificateStorage(const JID& profile) const {  				boost::filesystem::path profilePath = basePath / profile.toString(); -				return new CertificateFileStorage(profilePath / "certificates", certificateFactory); +				return new CertificateFileStorage(profilePath / "certificates", certificateFactory, crypto);  			}  		private:  			boost::filesystem::path basePath;  			CertificateFactory* certificateFactory; +			CryptoProvider* crypto;  	};  } diff --git a/Swift/Controllers/Storages/FileStorages.cpp b/Swift/Controllers/Storages/FileStorages.cpp index cff87d3..357c213 100644 --- a/Swift/Controllers/Storages/FileStorages.cpp +++ b/Swift/Controllers/Storages/FileStorages.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -13,11 +13,11 @@  namespace Swift { -FileStorages::FileStorages(const boost::filesystem::path& baseDir, const JID& jid) { +FileStorages::FileStorages(const boost::filesystem::path& baseDir, const JID& jid, CryptoProvider* crypto) {  	std::string profile = jid.toBare(); -	vcardStorage = new VCardFileStorage(baseDir / profile / "vcards"); +	vcardStorage = new VCardFileStorage(baseDir / profile / "vcards", crypto);  	capsStorage = new CapsFileStorage(baseDir / "caps"); -	avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars"); +	avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars", crypto);  	rosterStorage = new RosterFileStorage(baseDir / profile / "roster.xml");  #ifdef SWIFT_EXPERIMENTAL_HISTORY  	historyStorage = new SQLiteHistoryStorage((baseDir / "history.db").string()); diff --git a/Swift/Controllers/Storages/FileStorages.h b/Swift/Controllers/Storages/FileStorages.h index 5e89db8..1e914b9 100644 --- a/Swift/Controllers/Storages/FileStorages.h +++ b/Swift/Controllers/Storages/FileStorages.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -8,7 +8,7 @@  #include <boost/filesystem/path.hpp> -#include "Swiften/Client/Storages.h" +#include <Swiften/Client/Storages.h>  namespace Swift {  	class VCardFileStorage; @@ -17,6 +17,7 @@ namespace Swift {  	class RosterFileStorage;  	class HistoryStorage;  	class JID; +	class CryptoProvider;  	/**  	 * A storages implementation that stores all controller data on disk. @@ -37,7 +38,7 @@ namespace Swift {  			 * \param jid the subdir in which profile-specific data will be stored.   			 *   The bare JID will be used as the subdir name.  			 */ -			FileStorages(const boost::filesystem::path& baseDir, const JID& jid); +			FileStorages(const boost::filesystem::path& baseDir, const JID& jid, CryptoProvider*);  			~FileStorages();  			virtual VCardStorage* getVCardStorage() const; diff --git a/Swift/Controllers/Storages/FileStoragesFactory.h b/Swift/Controllers/Storages/FileStoragesFactory.h index 0676bc3..c119dcf 100644 --- a/Swift/Controllers/Storages/FileStoragesFactory.h +++ b/Swift/Controllers/Storages/FileStoragesFactory.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -10,15 +10,18 @@  #include "Swift/Controllers/Storages/FileStorages.h"  namespace Swift { +	class CryptoProvider; +  	class FileStoragesFactory : public StoragesFactory {  		public: -			FileStoragesFactory(const boost::filesystem::path& basePath) : basePath(basePath) {} +			FileStoragesFactory(const boost::filesystem::path& basePath, CryptoProvider* crypto) : basePath(basePath), crypto(crypto) {}  			virtual Storages* createStorages(const JID& profile) const { -				return new FileStorages(basePath, profile); +				return new FileStorages(basePath, profile, crypto);  			}  		private:  			boost::filesystem::path basePath; +			CryptoProvider* crypto;  	};  } diff --git a/Swift/Controllers/Storages/VCardFileStorage.cpp b/Swift/Controllers/Storages/VCardFileStorage.cpp index d799a90..633ed58 100644 --- a/Swift/Controllers/Storages/VCardFileStorage.cpp +++ b/Swift/Controllers/Storages/VCardFileStorage.cpp @@ -13,8 +13,8 @@  #include <Swiften/Entity/GenericPayloadPersister.h>  #include <Swiften/Base/String.h>  #include <Swiften/StringCodecs/Hexify.h> -#include <Swiften/StringCodecs/SHA1.h>  #include <Swiften/Base/foreach.h> +#include <Swiften/Crypto/CryptoProvider.h>  #include "Swiften/JID/JID.h"  #include "Swiften/Elements/VCard.h"  #include "Swiften/Serializer/PayloadSerializers/VCardSerializer.h" @@ -25,7 +25,7 @@ using namespace Swift;  typedef GenericPayloadPersister<VCard, VCardParser, VCardSerializer> VCardPersister; -VCardFileStorage::VCardFileStorage(boost::filesystem::path dir) : vcardsPath(dir) { +VCardFileStorage::VCardFileStorage(boost::filesystem::path dir, CryptoProvider* crypto) : VCardStorage(crypto), vcardsPath(dir), crypto(crypto) {  	cacheFile = vcardsPath / "phashes";  	if (boost::filesystem::exists(cacheFile)) {  		try { @@ -88,7 +88,7 @@ std::string VCardFileStorage::getPhotoHash(const JID& jid) const {  std::string VCardFileStorage::getAndUpdatePhotoHash(const JID& jid, VCard::ref vCard) const {  	std::string hash;  	if (vCard && !vCard->getPhoto().empty()) { -		hash = Hexify::hexify(SHA1::getHash(vCard->getPhoto())); +		hash = Hexify::hexify(crypto->getSHA1Hash(vCard->getPhoto()));  	}  	std::pair<PhotoHashMap::iterator, bool> r = photoHashes.insert(std::make_pair(jid, hash));  	if (r.second) { diff --git a/Swift/Controllers/Storages/VCardFileStorage.h b/Swift/Controllers/Storages/VCardFileStorage.h index ba422f4..2c3af3d 100644 --- a/Swift/Controllers/Storages/VCardFileStorage.h +++ b/Swift/Controllers/Storages/VCardFileStorage.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -14,9 +14,11 @@  #include "Swiften/VCards/VCardStorage.h"  namespace Swift { +	class CryptoProvider; +  	class VCardFileStorage : public VCardStorage {  		public: -			VCardFileStorage(boost::filesystem::path dir); +			VCardFileStorage(boost::filesystem::path dir, CryptoProvider* crypto);  			virtual VCard::ref getVCard(const JID& jid) const;  			virtual void setVCard(const JID& jid, VCard::ref v); @@ -31,6 +33,7 @@ namespace Swift {  		private:  			boost::filesystem::path vcardsPath; +			CryptoProvider* crypto;  			boost::filesystem::path cacheFile;  			typedef std::map<JID, std::string> PhotoHashMap;  			mutable PhotoHashMap photoHashes; diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index b44ee2f..839d079 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -159,8 +159,8 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa  	tabs_ = options.count("no-tabs") && !splitter_ ? NULL : new QtChatTabs(splitter_ != NULL);  	bool startMinimized = options.count("start-minimized") > 0;  	applicationPathProvider_ = new PlatformApplicationPathProvider(SWIFT_APPLICATION_NAME); -	storagesFactory_ = new FileStoragesFactory(applicationPathProvider_->getDataDir()); -	certificateStorageFactory_ = new CertificateFileStorageFactory(applicationPathProvider_->getDataDir(), tlsFactories_.getCertificateFactory()); +	storagesFactory_ = new FileStoragesFactory(applicationPathProvider_->getDataDir(), networkFactories_.getCryptoProvider()); +	certificateStorageFactory_ = new CertificateFileStorageFactory(applicationPathProvider_->getDataDir(), tlsFactories_.getCertificateFactory(), networkFactories_.getCryptoProvider());  	chatWindowFactory_ = new QtChatWindowFactory(splitter_, settingsHierachy_, qtSettings_, tabs_, "", emoticons);  	soundPlayer_ = new QtSoundPlayer(applicationPathProvider_); diff --git a/Swiften/Avatars/AvatarManagerImpl.cpp b/Swiften/Avatars/AvatarManagerImpl.cpp index 78d94dc..7c3baa7 100644 --- a/Swiften/Avatars/AvatarManagerImpl.cpp +++ b/Swiften/Avatars/AvatarManagerImpl.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -16,11 +16,11 @@  namespace Swift { -AvatarManagerImpl::AvatarManagerImpl(VCardManager* vcardManager, StanzaChannel* stanzaChannel, AvatarStorage* avatarStorage, MUCRegistry* mucRegistry) : avatarStorage(avatarStorage) { -	vcardUpdateAvatarManager = new VCardUpdateAvatarManager(vcardManager, stanzaChannel, avatarStorage, mucRegistry); +AvatarManagerImpl::AvatarManagerImpl(VCardManager* vcardManager, StanzaChannel* stanzaChannel, AvatarStorage* avatarStorage, CryptoProvider* crypto, MUCRegistry* mucRegistry) : avatarStorage(avatarStorage) { +	vcardUpdateAvatarManager = new VCardUpdateAvatarManager(vcardManager, stanzaChannel, avatarStorage, crypto, mucRegistry);  	combinedAvatarProvider.addProvider(vcardUpdateAvatarManager); -	vcardAvatarManager = new VCardAvatarManager(vcardManager, avatarStorage, mucRegistry); +	vcardAvatarManager = new VCardAvatarManager(vcardManager, avatarStorage, crypto, mucRegistry);  	combinedAvatarProvider.addProvider(vcardAvatarManager);  	offlineAvatarManager = new OfflineAvatarManager(avatarStorage); diff --git a/Swiften/Avatars/AvatarManagerImpl.h b/Swiften/Avatars/AvatarManagerImpl.h index c2b8956..4f59fe5 100644 --- a/Swiften/Avatars/AvatarManagerImpl.h +++ b/Swiften/Avatars/AvatarManagerImpl.h @@ -17,10 +17,11 @@ namespace Swift {  	class VCardUpdateAvatarManager;  	class VCardAvatarManager;  	class OfflineAvatarManager; +	class CryptoProvider;  	class AvatarManagerImpl : public AvatarManager {  		public: -			AvatarManagerImpl(VCardManager*, StanzaChannel*, AvatarStorage*, MUCRegistry* = NULL); +			AvatarManagerImpl(VCardManager*, StanzaChannel*, AvatarStorage*, CryptoProvider* crypto, MUCRegistry* = NULL);  			virtual ~AvatarManagerImpl();  			virtual boost::filesystem::path getAvatarPath(const JID&) const; diff --git a/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp b/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp index 81dc12c..dd76fb6 100644 --- a/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp +++ b/Swiften/Avatars/UnitTest/VCardAvatarManagerTest.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -19,8 +19,9 @@  #include <Swiften/MUC/MUCRegistry.h>  #include <Swiften/Queries/IQRouter.h>  #include <Swiften/Client/DummyStanzaChannel.h> -#include <Swiften/StringCodecs/SHA1.h>  #include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -37,6 +38,8 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture {  	public:  		class TestVCardStorage : public VCardStorage {  			public: +				TestVCardStorage(CryptoProvider* crypto) : VCardStorage(crypto), crypto(crypto) {} +  				virtual VCard::ref getVCard(const JID& jid) const {  					VCardMap::const_iterator i = vcards.find(jid);  					if (i != vcards.end()) { @@ -57,7 +60,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture {  					}  					VCard::ref vCard = getVCard(jid);  					if (vCard && !vCard->getPhoto().empty()) { -						return Hexify::hexify(SHA1::getHash(vCard->getPhoto())); +						return Hexify::hexify(crypto->getSHA1Hash(vCard->getPhoto()));  					}  					else {  						return ""; @@ -69,19 +72,21 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture {  			private:  				typedef std::map<JID, VCard::ref> VCardMap;  				VCardMap vcards; +				CryptoProvider* crypto;  		};  		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());  			ownJID = JID("foo@fum.com/bum");  			stanzaChannel = new DummyStanzaChannel();  			stanzaChannel->setAvailable(true);  			iqRouter = new IQRouter(stanzaChannel);  			mucRegistry = new DummyMUCRegistry();  			avatarStorage = new AvatarMemoryStorage(); -			vcardStorage = new TestVCardStorage(); +			vcardStorage = new TestVCardStorage(crypto.get());  			vcardManager = new VCardManager(ownJID, iqRouter, vcardStorage);  			avatar1 = createByteArray("abcdefg"); -			avatar1Hash = Hexify::hexify(SHA1::getHash(avatar1)); +			avatar1Hash = Hexify::hexify(crypto->getSHA1Hash(avatar1));  			user1 = JID("user1@bar.com/bla");  			user2 = JID("user2@foo.com/baz");  		} @@ -153,7 +158,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture {  	private:  		boost::shared_ptr<VCardAvatarManager> createManager() { -			boost::shared_ptr<VCardAvatarManager> result(new VCardAvatarManager(vcardManager, avatarStorage, mucRegistry)); +			boost::shared_ptr<VCardAvatarManager> result(new VCardAvatarManager(vcardManager, avatarStorage, crypto.get(), mucRegistry));  			result->onAvatarChanged.connect(boost::bind(&VCardAvatarManagerTest::handleAvatarChanged, this, _1));  			return result;  		} @@ -197,6 +202,7 @@ class VCardAvatarManagerTest : public CppUnit::TestFixture {  		std::vector<JID> changes;  		JID user1;  		JID user2; +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(VCardAvatarManagerTest); diff --git a/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp b/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp index 60e76f8..01b10a2 100644 --- a/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp +++ b/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -19,8 +19,9 @@  #include <Swiften/MUC/MUCRegistry.h>  #include <Swiften/Queries/IQRouter.h>  #include <Swiften/Client/DummyStanzaChannel.h> -#include <Swiften/StringCodecs/SHA1.h>  #include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -37,19 +38,21 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture {  	public:  		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());  			ownJID = JID("foo@fum.com/bum");  			stanzaChannel = new DummyStanzaChannel();  			stanzaChannel->setAvailable(true);  			iqRouter = new IQRouter(stanzaChannel);  			mucRegistry = new DummyMUCRegistry();  			avatarStorage = new AvatarMemoryStorage(); -			vcardStorage = new VCardMemoryStorage(); +			vcardStorage = new VCardMemoryStorage(crypto.get());  			vcardManager = new VCardManager(ownJID, iqRouter, vcardStorage);  			avatar1 = createByteArray("abcdefg"); -			avatar1Hash = Hexify::hexify(SHA1::getHash(avatar1)); +			avatar1Hash = Hexify::hexify(crypto->getSHA1Hash(avatar1));  			user1 = JID("user1@bar.com/bla");  			user2 = JID("user2@foo.com/baz");  		} +		  		void tearDown() {  			delete vcardManager; @@ -113,7 +116,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture {  			vcardManager->requestVCard(JID("foo@bar.com"));  			stanzaChannel->onIQReceived(createVCardResult(ByteArray())); -			CPPUNIT_ASSERT(!avatarStorage->hasAvatar(Hexify::hexify(SHA1::getHash(ByteArray())))); +			CPPUNIT_ASSERT(!avatarStorage->hasAvatar(Hexify::hexify(crypto->getSHA1Hash(ByteArray()))));  			CPPUNIT_ASSERT_EQUAL(std::string(), testling->getAvatarHash(JID("foo@bar.com")));  		} @@ -150,7 +153,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture {  	private:  		boost::shared_ptr<VCardUpdateAvatarManager> createManager() { -			boost::shared_ptr<VCardUpdateAvatarManager> result(new VCardUpdateAvatarManager(vcardManager, stanzaChannel, avatarStorage, mucRegistry)); +			boost::shared_ptr<VCardUpdateAvatarManager> result(new VCardUpdateAvatarManager(vcardManager, stanzaChannel, avatarStorage, crypto.get(), mucRegistry));  			result->onAvatarChanged.connect(boost::bind(&VCardUpdateAvatarManagerTest::handleAvatarChanged, this, _1));  			return result;  		} @@ -192,6 +195,7 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture {  		std::vector<JID> changes;  		JID user1;  		JID user2; +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(VCardUpdateAvatarManagerTest); diff --git a/Swiften/Avatars/VCardAvatarManager.cpp b/Swiften/Avatars/VCardAvatarManager.cpp index ef1d293..8212a6e 100644 --- a/Swiften/Avatars/VCardAvatarManager.cpp +++ b/Swiften/Avatars/VCardAvatarManager.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -9,7 +9,7 @@  #include <boost/bind.hpp>  #include <Swiften/Elements/VCard.h> -#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/Crypto/CryptoProvider.h>  #include <Swiften/StringCodecs/Hexify.h>  #include <Swiften/Avatars/AvatarStorage.h>  #include <Swiften/MUC/MUCRegistry.h> @@ -18,7 +18,7 @@  namespace Swift { -VCardAvatarManager::VCardAvatarManager(VCardManager* vcardManager, AvatarStorage* avatarStorage, MUCRegistry* mucRegistry) : vcardManager_(vcardManager), avatarStorage_(avatarStorage), mucRegistry_(mucRegistry) { +VCardAvatarManager::VCardAvatarManager(VCardManager* vcardManager, AvatarStorage* avatarStorage, CryptoProvider* crypto, MUCRegistry* mucRegistry) : vcardManager_(vcardManager), avatarStorage_(avatarStorage), crypto_(crypto), mucRegistry_(mucRegistry) {  	vcardManager_->onVCardChanged.connect(boost::bind(&VCardAvatarManager::handleVCardChanged, this, _1));  } @@ -36,7 +36,7 @@ std::string VCardAvatarManager::getAvatarHash(const JID& jid) const {  		if (!avatarStorage_->hasAvatar(hash)) {  			VCard::ref vCard = vcardManager_->getVCard(avatarJID);  			if (vCard) { -				std::string newHash = Hexify::hexify(SHA1::getHash(vCard->getPhoto())); +				std::string newHash = Hexify::hexify(crypto_->getSHA1Hash(vCard->getPhoto()));  				if (newHash != hash) {  					// Shouldn't happen, but sometimes seem to. Might be fixed if we  					// move to a safer backend. diff --git a/Swiften/Avatars/VCardAvatarManager.h b/Swiften/Avatars/VCardAvatarManager.h index ed2ba5d..9c6943e 100644 --- a/Swiften/Avatars/VCardAvatarManager.h +++ b/Swiften/Avatars/VCardAvatarManager.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -14,10 +14,11 @@ namespace Swift {  	class MUCRegistry;  	class AvatarStorage;  	class VCardManager; +	class CryptoProvider;  	class SWIFTEN_API VCardAvatarManager : public AvatarProvider {  		public: -			VCardAvatarManager(VCardManager*, AvatarStorage*, MUCRegistry* = NULL); +			VCardAvatarManager(VCardManager*, AvatarStorage*, CryptoProvider* crypto, MUCRegistry* = NULL);  			std::string getAvatarHash(const JID&) const; @@ -28,6 +29,7 @@ namespace Swift {  		private:  			VCardManager* vcardManager_;  			AvatarStorage* avatarStorage_; +			CryptoProvider* crypto_;  			MUCRegistry* mucRegistry_;  	};  } diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.cpp b/Swiften/Avatars/VCardUpdateAvatarManager.cpp index 3c086d5..adbefd5 100644 --- a/Swiften/Avatars/VCardUpdateAvatarManager.cpp +++ b/Swiften/Avatars/VCardUpdateAvatarManager.cpp @@ -11,7 +11,7 @@  #include <Swiften/Client/StanzaChannel.h>  #include <Swiften/Elements/VCardUpdate.h>  #include <Swiften/VCards/GetVCardRequest.h> -#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/Crypto/CryptoProvider.h>  #include <Swiften/StringCodecs/Hexify.h>  #include <Swiften/Avatars/AvatarStorage.h>  #include <Swiften/MUC/MUCRegistry.h> @@ -20,7 +20,7 @@  namespace Swift { -VCardUpdateAvatarManager::VCardUpdateAvatarManager(VCardManager* vcardManager, StanzaChannel* stanzaChannel, AvatarStorage* avatarStorage, MUCRegistry* mucRegistry) : vcardManager_(vcardManager), avatarStorage_(avatarStorage), mucRegistry_(mucRegistry) { +VCardUpdateAvatarManager::VCardUpdateAvatarManager(VCardManager* vcardManager, StanzaChannel* stanzaChannel, AvatarStorage* avatarStorage, CryptoProvider* crypto, MUCRegistry* mucRegistry) : vcardManager_(vcardManager), avatarStorage_(avatarStorage), crypto_(crypto), mucRegistry_(mucRegistry) {  	stanzaChannel->onPresenceReceived.connect(boost::bind(&VCardUpdateAvatarManager::handlePresenceReceived, this, _1));  	stanzaChannel->onAvailableChanged.connect(boost::bind(&VCardUpdateAvatarManager::handleStanzaChannelAvailableChanged, this, _1));  	vcardManager_->onVCardChanged.connect(boost::bind(&VCardUpdateAvatarManager::handleVCardChanged, this, _1, _2)); @@ -54,7 +54,7 @@ void VCardUpdateAvatarManager::handleVCardChanged(const JID& from, VCard::ref vC  		setAvatarHash(from, "");  	}  	else { -		std::string hash = Hexify::hexify(SHA1::getHash(vCard->getPhoto())); +		std::string hash = Hexify::hexify(crypto_->getSHA1Hash(vCard->getPhoto()));  		if (!avatarStorage_->hasAvatar(hash)) {  			avatarStorage_->addAvatar(hash, vCard->getPhoto());  		} diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.h b/Swiften/Avatars/VCardUpdateAvatarManager.h index 43e1d62..3409f99 100644 --- a/Swiften/Avatars/VCardUpdateAvatarManager.h +++ b/Swiften/Avatars/VCardUpdateAvatarManager.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -21,10 +21,11 @@ namespace Swift {  	class AvatarStorage;  	class StanzaChannel;  	class VCardManager; +	class CryptoProvider;  	class SWIFTEN_API VCardUpdateAvatarManager : public AvatarProvider, public boost::bsignals::trackable {  		public: -			VCardUpdateAvatarManager(VCardManager*, StanzaChannel*, AvatarStorage*, MUCRegistry* = NULL); +			VCardUpdateAvatarManager(VCardManager*, StanzaChannel*, AvatarStorage*, CryptoProvider* crypto, MUCRegistry* = NULL);  			std::string getAvatarHash(const JID&) const; @@ -38,6 +39,7 @@ namespace Swift {  		private:  			VCardManager* vcardManager_;  			AvatarStorage* avatarStorage_; +			CryptoProvider* crypto_;  			MUCRegistry* mucRegistry_;  			std::map<JID, std::string> avatarHashes_;  	}; diff --git a/Swiften/Base/Algorithm.h b/Swiften/Base/Algorithm.h index 4e68e70..d5edab1 100644 --- a/Swiften/Base/Algorithm.h +++ b/Swiften/Base/Algorithm.h @@ -99,6 +99,11 @@ namespace Swift {  		target.insert(target.end(), source.begin(), source.end());  	} +	template<typename Source, typename Target> +	void assign(Target& target, const Source& source) { +		target.assign(source.begin(), source.end()); +	} +  	template<typename A, typename B, typename C, typename D>   	B get(const std::map<A, B, C, D>& map, const A& key, const B& defaultValue) {  		typename std::map<A, B, C, D>::const_iterator i = map.find(key); diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp index 00f0f44..54e0b83 100644 --- a/Swiften/Client/Client.cpp +++ b/Swiften/Client/Client.cpp @@ -38,7 +38,7 @@  namespace Swift {  Client::Client(const JID& jid, const SafeString& password, NetworkFactories* networkFactories, Storages* storages) : CoreClient(jid, password, networkFactories), storages(storages) { -	memoryStorages = new MemoryStorages(); +	memoryStorages = new MemoryStorages(networkFactories->getCryptoProvider());  	softwareVersionResponder = new SoftwareVersionResponder(getIQRouter());  	softwareVersionResponder->start(); @@ -53,14 +53,14 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net  	stanzaChannelPresenceSender = new StanzaChannelPresenceSender(getStanzaChannel());  	directedPresenceSender = new DirectedPresenceSender(stanzaChannelPresenceSender); -	discoManager = new ClientDiscoManager(getIQRouter(), directedPresenceSender); +	discoManager = new ClientDiscoManager(getIQRouter(), directedPresenceSender, networkFactories->getCryptoProvider());  	mucRegistry = new MUCRegistry();  	mucManager = new MUCManager(getStanzaChannel(), getIQRouter(), directedPresenceSender, mucRegistry);  	vcardManager = new VCardManager(jid, getIQRouter(), getStorages()->getVCardStorage()); -	avatarManager = new AvatarManagerImpl(vcardManager, getStanzaChannel(), getStorages()->getAvatarStorage(), mucRegistry); -	capsManager = new CapsManager(getStorages()->getCapsStorage(), getStanzaChannel(), getIQRouter()); +	avatarManager = new AvatarManagerImpl(vcardManager, getStanzaChannel(), getStorages()->getAvatarStorage(), networkFactories->getCryptoProvider(), mucRegistry); +	capsManager = new CapsManager(getStorages()->getCapsStorage(), getStanzaChannel(), getIQRouter(), networkFactories->getCryptoProvider());  	entityCapsManager = new EntityCapsManager(capsManager, getStanzaChannel());  	nickManager = new NickManagerImpl(jid.toBare(), vcardManager); @@ -122,7 +122,7 @@ void Client::setSoftwareVersion(const std::string& name, const std::string& vers  void Client::handleConnected() {  #ifdef SWIFT_EXPERIMENTAL_FT -	fileTransferManager = new FileTransferManagerImpl(getJID(), jingleSessionManager, getIQRouter(), getEntityCapsProvider(), presenceOracle, getNetworkFactories()->getConnectionFactory(), getNetworkFactories()->getConnectionServerFactory(), getNetworkFactories()->getTimerFactory(), getNetworkFactories()->getNATTraverser()); +	fileTransferManager = new FileTransferManagerImpl(getJID(), jingleSessionManager, getIQRouter(), getEntityCapsProvider(), presenceOracle, getNetworkFactories()->getConnectionFactory(), getNetworkFactories()->getConnectionServerFactory(), getNetworkFactories()->getTimerFactory(), getNetworkFactories()->getNATTraverser(), getNetworkFactories()->getCryptoProvider());  #else  	fileTransferManager = new DummyFileTransferManager();  #endif diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp index c5a5c23..f03cbaa 100644 --- a/Swiften/Client/ClientSession.cpp +++ b/Swiften/Client/ClientSession.cpp @@ -40,6 +40,7 @@  #include <Swiften/SASL/EXTERNALClientAuthenticator.h>  #include <Swiften/SASL/SCRAMSHA1ClientAuthenticator.h>  #include <Swiften/SASL/DIGESTMD5ClientAuthenticator.h> +#include <Swiften/Crypto/CryptoProvider.h>  #include <Swiften/Session/SessionStream.h>  #include <Swiften/TLS/CertificateTrustChecker.h>  #include <Swiften/TLS/ServerIdentityVerifier.h> @@ -57,11 +58,13 @@ namespace Swift {  ClientSession::ClientSession(  		const JID& jid,   		boost::shared_ptr<SessionStream> stream, -		IDNConverter* idnConverter) : +		IDNConverter* idnConverter, +		CryptoProvider* crypto) :  			localJID(jid),	  			state(Initial),   			stream(stream),  			idnConverter(idnConverter), +			crypto(crypto),  			allowPLAINOverNonTLS(false),  			useStreamCompression(true),  			useTLS(UseTLSWhenAvailable), @@ -226,7 +229,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {  					plus &= !finishMessage.empty();  				}  				s << boost::uuids::random_generator()(); -				SCRAMSHA1ClientAuthenticator* scramAuthenticator = new SCRAMSHA1ClientAuthenticator(s.str(), plus, idnConverter); +				SCRAMSHA1ClientAuthenticator* scramAuthenticator = new SCRAMSHA1ClientAuthenticator(s.str(), plus, idnConverter, crypto);  				if (plus) {  					scramAuthenticator->setTLSChannelBindingData(finishMessage);  				} @@ -239,11 +242,11 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {  				state = WaitingForCredentials;  				onNeedCredentials();  			} -			else if (streamFeatures->hasAuthenticationMechanism("DIGEST-MD5") && DIGESTMD5ClientAuthenticator::canBeUsed()) { +			else if (streamFeatures->hasAuthenticationMechanism("DIGEST-MD5") && crypto->isMD5AllowedForCrypto()) {  				std::ostringstream s;  				s << boost::uuids::random_generator()();  				// FIXME: Host should probably be the actual host -				authenticator = new DIGESTMD5ClientAuthenticator(localJID.getDomain(), s.str()); +				authenticator = new DIGESTMD5ClientAuthenticator(localJID.getDomain(), s.str(), crypto);  				state = WaitingForCredentials;  				onNeedCredentials();  			} diff --git a/Swiften/Client/ClientSession.h b/Swiften/Client/ClientSession.h index 842412d..6ef624e 100644 --- a/Swiften/Client/ClientSession.h +++ b/Swiften/Client/ClientSession.h @@ -23,6 +23,7 @@ namespace Swift {  	class ClientAuthenticator;  	class CertificateTrustChecker;  	class IDNConverter; +	class CryptoProvider;  	class SWIFTEN_API ClientSession : public boost::enable_shared_from_this<ClientSession> {  		public: @@ -67,8 +68,8 @@ namespace Swift {  			~ClientSession(); -			static boost::shared_ptr<ClientSession> create(const JID& jid, boost::shared_ptr<SessionStream> stream, IDNConverter* idnConverter) { -				return boost::shared_ptr<ClientSession>(new ClientSession(jid, stream, idnConverter)); +			static boost::shared_ptr<ClientSession> create(const JID& jid, boost::shared_ptr<SessionStream> stream, IDNConverter* idnConverter, CryptoProvider* crypto) { +				return boost::shared_ptr<ClientSession>(new ClientSession(jid, stream, idnConverter, crypto));  			}  			State getState() const { @@ -133,7 +134,8 @@ namespace Swift {  			ClientSession(  					const JID& jid,   					boost::shared_ptr<SessionStream>, -					IDNConverter* idnConverter); +					IDNConverter* idnConverter, +					CryptoProvider* crypto);  			void finishSession(Error::Type error);  			void finishSession(boost::shared_ptr<Swift::Error> error); @@ -164,6 +166,7 @@ namespace Swift {  			State state;  			boost::shared_ptr<SessionStream> stream;  			IDNConverter* idnConverter; +			CryptoProvider* crypto;  			bool allowPLAINOverNonTLS;  			bool useStreamCompression;  			UseTLS useTLS; diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp index 07124ed..4438135 100644 --- a/Swiften/Client/CoreClient.cpp +++ b/Swiften/Client/CoreClient.cpp @@ -142,7 +142,7 @@ void CoreClient::connect(const ClientOptions& o) {  }  void CoreClient::bindSessionToStream() { -	session_ = ClientSession::create(jid_, sessionStream_, networkFactories->getIDNConverter()); +	session_ = ClientSession::create(jid_, sessionStream_, networkFactories->getIDNConverter(), networkFactories->getCryptoProvider());  	session_->setCertificateTrustChecker(certificateTrustChecker);  	session_->setUseStreamCompression(options.useStreamCompression);  	session_->setAllowPLAINOverNonTLS(options.allowPLAINWithoutTLS); diff --git a/Swiften/Client/MemoryStorages.cpp b/Swiften/Client/MemoryStorages.cpp index 703e9ff..885d74f 100644 --- a/Swiften/Client/MemoryStorages.cpp +++ b/Swiften/Client/MemoryStorages.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -13,8 +13,8 @@  namespace Swift { -MemoryStorages::MemoryStorages() { -	vcardStorage = new VCardMemoryStorage(); +MemoryStorages::MemoryStorages(CryptoProvider* crypto) { +	vcardStorage = new VCardMemoryStorage(crypto);  	capsStorage = new CapsMemoryStorage();  	avatarStorage = new AvatarMemoryStorage();  	rosterStorage = new RosterMemoryStorage(); diff --git a/Swiften/Client/MemoryStorages.h b/Swiften/Client/MemoryStorages.h index 403a89a..68ec285 100644 --- a/Swiften/Client/MemoryStorages.h +++ b/Swiften/Client/MemoryStorages.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -10,6 +10,7 @@  namespace Swift {  	class VCardMemoryStorage; +	class CryptoProvider;  	/**  	 * An implementation of Storages for storing all @@ -17,7 +18,7 @@ namespace Swift {  	 */  	class MemoryStorages : public Storages {  		public: -			MemoryStorages(); +			MemoryStorages(CryptoProvider*);  			~MemoryStorages();  			virtual VCardStorage* getVCardStorage() const; diff --git a/Swiften/Client/UnitTest/ClientSessionTest.cpp b/Swiften/Client/UnitTest/ClientSessionTest.cpp index 63c922c..4ef6727 100644 --- a/Swiften/Client/UnitTest/ClientSessionTest.cpp +++ b/Swiften/Client/UnitTest/ClientSessionTest.cpp @@ -33,6 +33,8 @@  #include <Swiften/Elements/ResourceBind.h>  #include <Swiften/TLS/SimpleCertificate.h>  #include <Swiften/TLS/BlindCertificateTrustChecker.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -71,6 +73,7 @@ class ClientSessionTest : public CppUnit::TestFixture {  	public:  		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());  			idnConverter = boost::shared_ptr<IDNConverter>(PlatformIDNConverter::create());  			server = boost::make_shared<MockSessionStream>();  			sessionFinishedReceived = false; @@ -342,7 +345,7 @@ class ClientSessionTest : public CppUnit::TestFixture {  	private:  		boost::shared_ptr<ClientSession> createSession() { -			boost::shared_ptr<ClientSession> session = ClientSession::create(JID("me@foo.com"), server, idnConverter.get()); +			boost::shared_ptr<ClientSession> session = ClientSession::create(JID("me@foo.com"), server, idnConverter.get(), crypto.get());  			session->onFinished.connect(boost::bind(&ClientSessionTest::handleSessionFinished, this, _1));  			session->onNeedCredentials.connect(boost::bind(&ClientSessionTest::handleSessionNeedCredentials, this));  			session->setAllowPLAINOverNonTLS(true); @@ -625,6 +628,7 @@ class ClientSessionTest : public CppUnit::TestFixture {  		bool needCredentials;  		boost::shared_ptr<Error> sessionFinishedError;  		BlindCertificateTrustChecker* blindCertificateTrustChecker; +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(ClientSessionTest); diff --git a/Swiften/Client/UnitTest/NickResolverTest.cpp b/Swiften/Client/UnitTest/NickResolverTest.cpp index dfc90fe..a8b011c 100644 --- a/Swiften/Client/UnitTest/NickResolverTest.cpp +++ b/Swiften/Client/UnitTest/NickResolverTest.cpp @@ -4,6 +4,12 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h> @@ -14,6 +20,8 @@  #include <Swiften/VCards/VCardMemoryStorage.h>  #include <Swiften/Queries/IQRouter.h>  #include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -34,11 +42,12 @@ class NickResolverTest : public CppUnit::TestFixture {  	public:  		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());  			ownJID_ = JID("kev@wonderland.lit");  			xmppRoster_ = new XMPPRosterImpl();  			stanzaChannel_ = new DummyStanzaChannel();  		  iqRouter_ = new IQRouter(stanzaChannel_); -			vCardStorage_ = new VCardMemoryStorage(); +			vCardStorage_ = new VCardMemoryStorage(crypto.get());  			vCardManager_ = new VCardManager(ownJID_, iqRouter_, vCardStorage_);  			registry_ = new MUCRegistry();  			resolver_ = new NickResolver(ownJID_, xmppRoster_, vCardManager_, registry_); @@ -144,7 +153,7 @@ class NickResolverTest : public CppUnit::TestFixture {  		MUCRegistry* registry_;  		NickResolver* resolver_;  		JID ownJID_; - +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(NickResolverTest); diff --git a/Swiften/Component/ComponentHandshakeGenerator.cpp b/Swiften/Component/ComponentHandshakeGenerator.cpp index 79ba9b3..495d530 100644 --- a/Swiften/Component/ComponentHandshakeGenerator.cpp +++ b/Swiften/Component/ComponentHandshakeGenerator.cpp @@ -6,19 +6,19 @@  #include <Swiften/Component/ComponentHandshakeGenerator.h>  #include <Swiften/StringCodecs/Hexify.h> -#include <Swiften/StringCodecs/SHA1.h>  #include <Swiften/Base/String.h> +#include <Swiften/Crypto/CryptoProvider.h>  namespace Swift { -std::string ComponentHandshakeGenerator::getHandshake(const std::string& streamID, const std::string& secret) { +std::string ComponentHandshakeGenerator::getHandshake(const std::string& streamID, const std::string& secret, CryptoProvider* crypto) {  	std::string concatenatedString = streamID + secret;  	String::replaceAll(concatenatedString, '&', "&");  	String::replaceAll(concatenatedString, '<', "<");  	String::replaceAll(concatenatedString, '>', ">");  	String::replaceAll(concatenatedString, '\'', "'");  	String::replaceAll(concatenatedString, '"', """); -	return Hexify::hexify(SHA1::getHash(createByteArray(concatenatedString))); +	return Hexify::hexify(crypto->getSHA1Hash(createByteArray(concatenatedString)));  }  } diff --git a/Swiften/Component/ComponentHandshakeGenerator.h b/Swiften/Component/ComponentHandshakeGenerator.h index c897fdc..e0e3ef8 100644 --- a/Swiften/Component/ComponentHandshakeGenerator.h +++ b/Swiften/Component/ComponentHandshakeGenerator.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -11,9 +11,11 @@  #include <Swiften/Base/API.h>  namespace Swift { +	class CryptoProvider; +  	class SWIFTEN_API ComponentHandshakeGenerator {  		public: -			static std::string getHandshake(const std::string& streamID, const std::string& secret); +			static std::string getHandshake(const std::string& streamID, const std::string& secret, CryptoProvider* crypto);  	};  } diff --git a/Swiften/Component/ComponentSession.cpp b/Swiften/Component/ComponentSession.cpp index 3269f23..7925b23 100644 --- a/Swiften/Component/ComponentSession.cpp +++ b/Swiften/Component/ComponentSession.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -17,7 +17,7 @@  namespace Swift { -ComponentSession::ComponentSession(const JID& jid, const std::string& secret, boost::shared_ptr<SessionStream> stream) : jid(jid), secret(secret), stream(stream), state(Initial) { +ComponentSession::ComponentSession(const JID& jid, const std::string& secret, boost::shared_ptr<SessionStream> stream, CryptoProvider* crypto) : jid(jid), secret(secret), stream(stream), crypto(crypto), state(Initial) {  }  ComponentSession::~ComponentSession() { @@ -46,7 +46,7 @@ void ComponentSession::sendStanza(boost::shared_ptr<Stanza> stanza) {  void ComponentSession::handleStreamStart(const ProtocolHeader& header) {  	checkState(WaitingForStreamStart);  	state = Authenticating; -	stream->writeElement(ComponentHandshake::ref(new ComponentHandshake(ComponentHandshakeGenerator::getHandshake(header.getID(), secret)))); +	stream->writeElement(ComponentHandshake::ref(new ComponentHandshake(ComponentHandshakeGenerator::getHandshake(header.getID(), secret, crypto))));  }  void ComponentSession::handleElement(boost::shared_ptr<Element> element) { diff --git a/Swiften/Component/ComponentSession.h b/Swiften/Component/ComponentSession.h index bc1ea5f..3103335 100644 --- a/Swiften/Component/ComponentSession.h +++ b/Swiften/Component/ComponentSession.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -20,6 +20,7 @@  namespace Swift {  	class ComponentAuthenticator; +	class CryptoProvider;  	class SWIFTEN_API ComponentSession : public boost::enable_shared_from_this<ComponentSession> {  		public: @@ -42,8 +43,8 @@ namespace Swift {  			~ComponentSession(); -			static boost::shared_ptr<ComponentSession> create(const JID& jid, const std::string& secret, boost::shared_ptr<SessionStream> stream) { -				return boost::shared_ptr<ComponentSession>(new ComponentSession(jid, secret, stream)); +			static boost::shared_ptr<ComponentSession> create(const JID& jid, const std::string& secret, boost::shared_ptr<SessionStream> stream, CryptoProvider* crypto) { +				return boost::shared_ptr<ComponentSession>(new ComponentSession(jid, secret, stream, crypto));  			}  			State getState() const { @@ -61,7 +62,7 @@ namespace Swift {  			boost::signal<void (boost::shared_ptr<Stanza>)> onStanzaReceived;  		private: -			ComponentSession(const JID& jid, const std::string& secret, boost::shared_ptr<SessionStream>); +			ComponentSession(const JID& jid, const std::string& secret, boost::shared_ptr<SessionStream>, CryptoProvider*);  			void finishSession(Error::Type error);  			void finishSession(boost::shared_ptr<Swift::Error> error); @@ -78,6 +79,7 @@ namespace Swift {  			JID jid;  			std::string secret;  			boost::shared_ptr<SessionStream> stream; +			CryptoProvider* crypto;  			boost::shared_ptr<Swift::Error> error;  			State state;  	}; diff --git a/Swiften/Component/CoreComponent.cpp b/Swiften/Component/CoreComponent.cpp index aac2d89..de3b66e 100644 --- a/Swiften/Component/CoreComponent.cpp +++ b/Swiften/Component/CoreComponent.cpp @@ -67,7 +67,7 @@ void CoreComponent::handleConnectorFinished(boost::shared_ptr<Connection> connec  		sessionStream_->onDataRead.connect(boost::bind(&CoreComponent::handleDataRead, this, _1));  		sessionStream_->onDataWritten.connect(boost::bind(&CoreComponent::handleDataWritten, this, _1)); -		session_ = ComponentSession::create(jid_, secret_, sessionStream_); +		session_ = ComponentSession::create(jid_, secret_, sessionStream_, networkFactories->getCryptoProvider());  		stanzaChannel_->setSession(session_);  		session_->onFinished.connect(boost::bind(&CoreComponent::handleSessionFinished, this, _1));  		session_->start(); diff --git a/Swiften/Component/UnitTest/ComponentHandshakeGeneratorTest.cpp b/Swiften/Component/UnitTest/ComponentHandshakeGeneratorTest.cpp index fd8f6fc..280e46e 100644 --- a/Swiften/Component/UnitTest/ComponentHandshakeGeneratorTest.cpp +++ b/Swiften/Component/UnitTest/ComponentHandshakeGeneratorTest.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -8,6 +8,8 @@  #include <cppunit/extensions/TestFactoryRegistry.h>  #include <Swiften/Component/ComponentHandshakeGenerator.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -18,16 +20,22 @@ class ComponentHandshakeGeneratorTest : public CppUnit::TestFixture {  		CPPUNIT_TEST_SUITE_END();  	public: +		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); +		} +  		void testGetHandshake() { -			std::string result = ComponentHandshakeGenerator::getHandshake("myid", "mysecret"); +			std::string result = ComponentHandshakeGenerator::getHandshake("myid", "mysecret", crypto.get());  			CPPUNIT_ASSERT_EQUAL(std::string("4011cd31f9b99ac089a0cd7ce297da7323fa2525"), result);  		}  		void testGetHandshake_SpecialChars() { -			std::string result = ComponentHandshakeGenerator::getHandshake("&<", ">'\""); +			std::string result = ComponentHandshakeGenerator::getHandshake("&<", ">'\"", crypto.get());  			CPPUNIT_ASSERT_EQUAL(std::string("33631b3e0aaeb2a11c4994c917919324028873fe"), result);  		} +	private: +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(ComponentHandshakeGeneratorTest); diff --git a/Swiften/Component/UnitTest/ComponentSessionTest.cpp b/Swiften/Component/UnitTest/ComponentSessionTest.cpp index 238d0b0..97fde63 100644 --- a/Swiften/Component/UnitTest/ComponentSessionTest.cpp +++ b/Swiften/Component/UnitTest/ComponentSessionTest.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -14,6 +14,8 @@  #include <Swiften/Component/ComponentSession.h>  #include <Swiften/Elements/ComponentHandshake.h>  #include <Swiften/Elements/AuthFailure.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -28,6 +30,7 @@ class ComponentSessionTest : public CppUnit::TestFixture {  		void setUp() {  			server = boost::make_shared<MockSessionStream>();  			sessionFinishedReceived = false; +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());  		}  		void testStart() { @@ -70,7 +73,7 @@ class ComponentSessionTest : public CppUnit::TestFixture {  	private:  		boost::shared_ptr<ComponentSession> createSession() { -			boost::shared_ptr<ComponentSession> session = ComponentSession::create(JID("service.foo.com"), "servicesecret", server); +			boost::shared_ptr<ComponentSession> session = ComponentSession::create(JID("service.foo.com"), "servicesecret", server, crypto.get());  			session->onFinished.connect(boost::bind(&ComponentSessionTest::handleSessionFinished, this, _1));  			return session;  		} @@ -212,6 +215,7 @@ class ComponentSessionTest : public CppUnit::TestFixture {  		bool sessionFinishedReceived;  		bool needCredentials;  		boost::shared_ptr<Error> sessionFinishedError; +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(ComponentSessionTest); diff --git a/Swiften/Crypto/CommonCryptoCryptoProvider.cpp b/Swiften/Crypto/CommonCryptoCryptoProvider.cpp new file mode 100644 index 0000000..f1810ba --- /dev/null +++ b/Swiften/Crypto/CommonCryptoCryptoProvider.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#include <Swiften/Crypto/CommonCryptoCryptoProvider.h> + +#include <CommonCrypto/CommonDigest.h> +#include <CommonCrypto/CommonHMAC.h> +#include <cassert> + +#include <Swiften/Crypto/Hash.h> +#include <Swiften/Base/ByteArray.h> +#include <boost/numeric/conversion/cast.hpp> + +using namespace Swift; + +namespace { +	class SHA1Hash : public Hash { +		public: +			SHA1Hash() : finalized(false) { +				if (!CC_SHA1_Init(&context)) { +					assert(false); +				} +			} + +			~SHA1Hash() { +			} + +			virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual std::vector<unsigned char> getHash() { +				assert(!finalized); +				std::vector<unsigned char> result(CC_SHA1_DIGEST_LENGTH); +				CC_SHA1_Final(vecptr(result), &context); +				return result; +			} + +		private: +			template<typename ContainerType> +			Hash& updateInternal(const ContainerType& data) { +				assert(!finalized); +				if (!CC_SHA1_Update(&context, vecptr(data), boost::numeric_cast<CC_LONG>(data.size()))) { +					assert(false); +				} +				return *this; +			} + +		private: +			CC_SHA1_CTX context; +			bool finalized; +	}; + +	class MD5Hash : public Hash { +		public: +			MD5Hash() : finalized(false) { +				if (!CC_MD5_Init(&context)) { +					assert(false); +				} +			} + +			~MD5Hash() { +			} + +			virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual std::vector<unsigned char> getHash() { +				assert(!finalized); +				std::vector<unsigned char> result(CC_MD5_DIGEST_LENGTH); +				CC_MD5_Final(vecptr(result), &context); +				return result; +			} + +		private: +			template<typename ContainerType> +			Hash& updateInternal(const ContainerType& data) { +				assert(!finalized); +				if (!CC_MD5_Update(&context, vecptr(data), boost::numeric_cast<CC_LONG>(data.size()))) { +					assert(false); +				} +				return *this; +			} + +		private: +			CC_MD5_CTX context; +			bool finalized; +	}; + +	template<typename T> +	class HMACHash : public Hash { +		public: +			HMACHash(const T& key) : finalized(false) { +				CCHmacInit(&context, kCCHmacAlgSHA1, vecptr(key), key.size()); +			} + +			~HMACHash() { +			} + +			virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual std::vector<unsigned char> getHash() { +				assert(!finalized); +				std::vector<unsigned char> result(CC_SHA1_DIGEST_LENGTH); +				CCHmacFinal(&context, vecptr(result)); +				return result; +			} + +		private: +			template<typename ContainerType> +			Hash& updateInternal(const ContainerType& data) { +				assert(!finalized); +				CCHmacUpdate(&context, vecptr(data), boost::numeric_cast<CC_LONG>(data.size())); +				return *this; +			} + +		private: +			CCHmacContext context; +			bool finalized; +	}; +} + +CommonCryptoCryptoProvider::CommonCryptoCryptoProvider() { +} + +CommonCryptoCryptoProvider::~CommonCryptoCryptoProvider() { +} + +Hash* CommonCryptoCryptoProvider::createSHA1() { +	return new SHA1Hash(); +} + +Hash* CommonCryptoCryptoProvider::createMD5() { +	return new MD5Hash(); +} + +Hash* CommonCryptoCryptoProvider::createHMACSHA1(const SafeByteArray& key) { +	return new HMACHash<SafeByteArray>(key); +} + +Hash* CommonCryptoCryptoProvider::createHMACSHA1(const ByteArray& key) { +	return new HMACHash<ByteArray>(key); +} + + +bool CommonCryptoCryptoProvider::isMD5AllowedForCrypto() const { +	return true; +} + diff --git a/Swiften/Crypto/CommonCryptoCryptoProvider.h b/Swiften/Crypto/CommonCryptoCryptoProvider.h new file mode 100644 index 0000000..8072c0d --- /dev/null +++ b/Swiften/Crypto/CommonCryptoCryptoProvider.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#pragma once + +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Base/Override.h> + +namespace Swift { +	class CommonCryptoCryptoProvider : public CryptoProvider { +		public: +			CommonCryptoCryptoProvider(); +			~CommonCryptoCryptoProvider(); + +			virtual Hash* createSHA1() SWIFTEN_OVERRIDE; +			virtual Hash* createMD5() SWIFTEN_OVERRIDE; +			virtual Hash* createHMACSHA1(const SafeByteArray& key) SWIFTEN_OVERRIDE; +			virtual Hash* createHMACSHA1(const ByteArray& key) SWIFTEN_OVERRIDE; +			virtual bool isMD5AllowedForCrypto() const SWIFTEN_OVERRIDE; +	}; +} diff --git a/Swiften/Crypto/CryptoProvider.cpp b/Swiften/Crypto/CryptoProvider.cpp new file mode 100644 index 0000000..0189de4 --- /dev/null +++ b/Swiften/Crypto/CryptoProvider.cpp @@ -0,0 +1,14 @@ +/*
 + * Copyright (c) 2013 Remko Tronçon
 + * Licensed under the GNU General Public License.
 + * See the COPYING file for more information.
 + */
 +
 +#include <Swiften/Crypto/CryptoProvider.h>
 +
 +#include <boost/shared_ptr.hpp>
 +
 +using namespace Swift;
 +
 +CryptoProvider::~CryptoProvider() {
 +}
 diff --git a/Swiften/Crypto/CryptoProvider.h b/Swiften/Crypto/CryptoProvider.h new file mode 100644 index 0000000..afee8c4 --- /dev/null +++ b/Swiften/Crypto/CryptoProvider.h @@ -0,0 +1,39 @@ +/*
 + * Copyright (c) 2013 Remko Tronçon
 + * Licensed under the GNU General Public License.
 + * See the COPYING file for more information.
 + */
 +
 +#pragma once
 +
 +#include <Swiften/Base/ByteArray.h>
 +#include <Swiften/Base/SafeByteArray.h>
 +#include <Swiften/Crypto/Hash.h>
 +
 +namespace Swift {
 +	class Hash;
 +
 +	class CryptoProvider {
 +		public:
 +			virtual ~CryptoProvider();
 +
 +			virtual Hash* createSHA1() = 0;
 +			virtual Hash* createMD5() = 0;
 +			virtual Hash* createHMACSHA1(const SafeByteArray& key) = 0;
 +			virtual Hash* createHMACSHA1(const ByteArray& key) = 0;
 +			virtual bool isMD5AllowedForCrypto() const = 0;
 +
 +			// Convenience
 +			template<typename T> ByteArray getSHA1Hash(const T& data) {
 +				return boost::shared_ptr<Hash>(createSHA1())->update(data).getHash();
 +			}
 +
 +			template<typename T> ByteArray getMD5Hash(const T& data) {
 +				return boost::shared_ptr<Hash>(createMD5())->update(data).getHash();
 +			}
 +
 +			template<typename T, typename U> ByteArray getHMACSHA1(const T& key, const U& data) {
 +				return boost::shared_ptr<Hash>(createHMACSHA1(key))->update(data).getHash();
 +			}
 +	};
 +}
 diff --git a/Swiften/Crypto/Hash.cpp b/Swiften/Crypto/Hash.cpp new file mode 100644 index 0000000..35c7e70 --- /dev/null +++ b/Swiften/Crypto/Hash.cpp @@ -0,0 +1,12 @@ +/*
 + * Copyright (c) 2013 Remko Tronçon
 + * Licensed under the GNU General Public License.
 + * See the COPYING file for more information.
 + */
 +
 +#include <Swiften/Crypto/Hash.h>
 +
 +using namespace Swift;
 +
 +Hash::~Hash() {
 +}
 diff --git a/Swiften/Crypto/Hash.h b/Swiften/Crypto/Hash.h new file mode 100644 index 0000000..37c6ec8 --- /dev/null +++ b/Swiften/Crypto/Hash.h @@ -0,0 +1,24 @@ +/*
 + * Copyright (c) 2013  Remko Tronçon
 + * Licensed under the GNU General Public License.
 + * See the COPYING file for more information.
 + */
 +
 +#pragma once
 +
 +#include <vector>
 +
 +#include <Swiften/Base/ByteArray.h>
 +#include <Swiften/Base/SafeByteArray.h>
 +
 +namespace Swift {
 +	class Hash {
 +		public:
 +			virtual ~Hash();
 +
 +			virtual Hash& update(const ByteArray& data) = 0;
 +			virtual Hash& update(const SafeByteArray& data) = 0;
 +
 +			virtual std::vector<unsigned char> getHash() = 0;
 +	};
 +}
 diff --git a/Swiften/Crypto/OpenSSLCryptoProvider.cpp b/Swiften/Crypto/OpenSSLCryptoProvider.cpp new file mode 100644 index 0000000..afe73aa --- /dev/null +++ b/Swiften/Crypto/OpenSSLCryptoProvider.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#include <Swiften/Crypto/OpenSSLCryptoProvider.h> + +#include <openssl/sha.h> +#include <openssl/md5.h> +#include <openssl/hmac.h> +#include <cassert> +#include <boost/numeric/conversion/cast.hpp> + +#include <Swiften/Crypto/Hash.h> +#include <Swiften/Base/ByteArray.h> + +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +using namespace Swift; + +namespace { +	class SHA1Hash : public Hash { +		public: +			SHA1Hash() : finalized(false) { +				if (!SHA1_Init(&context)) { +					assert(false); +				} +			} + +			~SHA1Hash() { +			} + +			virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual std::vector<unsigned char> getHash() { +				assert(!finalized); +				std::vector<unsigned char> result(SHA_DIGEST_LENGTH); +				SHA1_Final(vecptr(result), &context); +				return result; +			} + +		private: +			template<typename ContainerType> +			Hash& updateInternal(const ContainerType& data) { +				assert(!finalized); +				if (!SHA1_Update(&context, vecptr(data), data.size())) { +					assert(false); +				} +				return *this; +			} + +		private: +			SHA_CTX context; +			bool finalized; +	}; + +	class MD5Hash : public Hash { +		public: +			MD5Hash() : finalized(false) { +				if (!MD5_Init(&context)) { +					assert(false); +				} +			} + +			~MD5Hash() { +			} + +			virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual std::vector<unsigned char> getHash() { +				assert(!finalized); +				std::vector<unsigned char> result(MD5_DIGEST_LENGTH); +				MD5_Final(vecptr(result), &context); +				return result; +			} + +		private: +			template<typename ContainerType> +			Hash& updateInternal(const ContainerType& data) { +				assert(!finalized); +				if (!MD5_Update(&context, vecptr(data), data.size())) { +					assert(false); +				} +				return *this; +			} + +		private: +			MD5_CTX context; +			bool finalized; +	}; + + +	template<typename T> +	class HMACHash : public Hash { +		public: +			HMACHash(const T& key) : finalized(false) { +				HMAC_CTX_init(&context); +				HMAC_Init(&context, vecptr(key), boost::numeric_cast<int>(key.size()), EVP_sha1()); +			} + +			~HMACHash() { +				HMAC_CTX_cleanup(&context); +			} + +			virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE { +				return updateInternal(data); +			} + +			virtual std::vector<unsigned char> getHash() { +				assert(!finalized); +				std::vector<unsigned char> result(SHA_DIGEST_LENGTH); +				unsigned int len = SHA_DIGEST_LENGTH; +				HMAC_Final(&context, vecptr(result), &len); +				return result; +			} + +		private: +			template<typename ContainerType> +			Hash& updateInternal(const ContainerType& data) { +				assert(!finalized); +				HMAC_Update(&context, vecptr(data), data.size()); +				return *this; +			} + +		private: +			HMAC_CTX context; +			bool finalized; +	}; +} + +OpenSSLCryptoProvider::OpenSSLCryptoProvider() { +} + +OpenSSLCryptoProvider::~OpenSSLCryptoProvider() { +} + +Hash* OpenSSLCryptoProvider::createSHA1() { +	return new SHA1Hash(); +} + +Hash* OpenSSLCryptoProvider::createMD5() { +	return new MD5Hash(); +} + +Hash* OpenSSLCryptoProvider::createHMACSHA1(const SafeByteArray& key) { +	return new HMACHash<SafeByteArray>(key); +} + +Hash* OpenSSLCryptoProvider::createHMACSHA1(const ByteArray& key) { +	return new HMACHash<ByteArray>(key); +} + +bool OpenSSLCryptoProvider::isMD5AllowedForCrypto() const { +	return true; +} + diff --git a/Swiften/Crypto/OpenSSLCryptoProvider.h b/Swiften/Crypto/OpenSSLCryptoProvider.h new file mode 100644 index 0000000..e9ca37b --- /dev/null +++ b/Swiften/Crypto/OpenSSLCryptoProvider.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2013  Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#pragma once + +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Base/Override.h> + +namespace Swift { +	class OpenSSLCryptoProvider : public CryptoProvider { +		public: +			OpenSSLCryptoProvider(); +			~OpenSSLCryptoProvider(); + +			virtual Hash* createSHA1() SWIFTEN_OVERRIDE; +			virtual Hash* createMD5() SWIFTEN_OVERRIDE; +			virtual Hash* createHMACSHA1(const SafeByteArray& key) SWIFTEN_OVERRIDE; +			virtual Hash* createHMACSHA1(const ByteArray& key) SWIFTEN_OVERRIDE; +			virtual bool isMD5AllowedForCrypto() const SWIFTEN_OVERRIDE; +	}; +} diff --git a/Swiften/Crypto/PlatformCryptoProvider.cpp b/Swiften/Crypto/PlatformCryptoProvider.cpp new file mode 100644 index 0000000..ab0fa7b --- /dev/null +++ b/Swiften/Crypto/PlatformCryptoProvider.cpp @@ -0,0 +1,32 @@ +/*
 + * Copyright (c) 2013 Remko Tronçon
 + * Licensed under the GNU General Public License.
 + * See the COPYING file for more information.
 + */
 +
 +#include <Swiften/Crypto/PlatformCryptoProvider.h>
 +
 +#include <cassert>
 +
 +#include <Swiften/Base/Platform.h>
 +#if defined(SWIFTEN_PLATFORM_WIN32)
 +#include <Swiften/Crypto/WindowsCryptoProvider.h>
 +#elif defined(HAVE_COMMONCRYPTO_CRYPTO_PROVIDER)
 +#include <Swiften/Crypto/CommonCryptoCryptoProvider.h>
 +#elif defined(HAVE_OPENSSL_CRYPTO_PROVIDER)
 +#include <Swiften/Crypto/OpenSSLCryptoProvider.h>
 +#endif
 +
 +using namespace Swift;
 +
 +CryptoProvider* PlatformCryptoProvider::create() {
 +#if defined(SWIFTEN_PLATFORM_WIN32)
 +	return new WindowsCryptoProvider();
 +#elif defined(HAVE_COMMONCRYPTO_CRYPTO_PROVIDER)
 +	return new CommonCryptoCryptoProvider();
 +#elif defined(HAVE_OPENSSL_CRYPTO_PROVIDER)
 +	return new OpenSSLCryptoProvider();
 +#endif
 +	assert(false);
 +	return NULL;
 +}
 diff --git a/Swiften/Crypto/PlatformCryptoProvider.h b/Swiften/Crypto/PlatformCryptoProvider.h new file mode 100644 index 0000000..0721887 --- /dev/null +++ b/Swiften/Crypto/PlatformCryptoProvider.h @@ -0,0 +1,17 @@ +/*
 + * Copyright (c) 2013 Remko Tronçon
 + * Licensed under the GNU General Public License.
 + * See the COPYING file for more information.
 + */
 +
 +#pragma once
 +
 +#include <Swiften/Base/API.h>
 +
 +namespace Swift {
 +	class CryptoProvider;
 +
 +	namespace PlatformCryptoProvider {
 +		SWIFTEN_API CryptoProvider* create();
 +	}
 +}
 diff --git a/Swiften/Crypto/SConscript b/Swiften/Crypto/SConscript new file mode 100644 index 0000000..ce4bdae --- /dev/null +++ b/Swiften/Crypto/SConscript @@ -0,0 +1,28 @@ +Import("swiften_env", "env")
 +
 +
 +objects = swiften_env.SwiftenObject([
 +	"CryptoProvider.cpp",
 +	"Hash.cpp"
 +])
 +
 +myenv = swiften_env.Clone()
 +if myenv["PLATFORM"] == "win32" :
 +	objects += myenv.SwiftenObject(["WindowsCryptoProvider.cpp"])
 +if myenv.get("HAVE_OPENSSL", False) :
 +	myenv.Append(CPPDEFINES = ["HAVE_OPENSSL_CRYPTO_PROVIDER"])
 +	objects += myenv.SwiftenObject(["OpenSSLCryptoProvider.cpp"])
 +if myenv["PLATFORM"] == "darwin" and myenv["target"] == "native" :
 +	myenv.Append(CPPDEFINES = ["HAVE_COMMONCRYPTO_CRYPTO_PROVIDER"])
 +	objects += myenv.SwiftenObject(["CommonCryptoCryptoProvider.cpp"])
 +
 +objects += myenv.SwiftenObject(["PlatformCryptoProvider.cpp"])
 +
 +swiften_env.Append(SWIFTEN_OBJECTS = [objects])
 +
 +if env["TEST"] :
 +	test_env = myenv.Clone()
 +	test_env.UseFlags(swiften_env["CPPUNIT_FLAGS"])
 +	env.Append(UNITTEST_OBJECTS = test_env.SwiftenObject([
 +				File("UnitTest/CryptoProviderTest.cpp"),
 +	]))
 diff --git a/Swiften/Crypto/UnitTest/CryptoProviderTest.cpp b/Swiften/Crypto/UnitTest/CryptoProviderTest.cpp new file mode 100644 index 0000000..1e2275a --- /dev/null +++ b/Swiften/Crypto/UnitTest/CryptoProviderTest.cpp @@ -0,0 +1,156 @@ +/*
 + * Copyright (c) 2010-2013 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 <Swiften/Base/Platform.h>
 +#include <QA/Checker/IO.h>
 +
 +#include <cppunit/extensions/HelperMacros.h>
 +#include <cppunit/extensions/TestFactoryRegistry.h>
 +
 +#ifdef SWIFTEN_PLATFORM_WIN32
 +#include <Swiften/Crypto/WindowsCryptoProvider.h>
 +#endif
 +#ifdef HAVE_OPENSSL_CRYPTO_PROVIDER
 +#include <Swiften/Crypto/OpenSSLCryptoProvider.h>
 +#endif
 +#ifdef HAVE_OPENSSL_CRYPTO_PROVIDER
 +#include <Swiften/Crypto/CommonCryptoCryptoProvider.h>
 +#endif
 +#include <Swiften/Crypto/Hash.h>
 +
 +using namespace Swift;
 +
 +template <typename CryptoProviderType>
 +class CryptoProviderTest : public CppUnit::TestFixture {
 +		CPPUNIT_TEST_SUITE(CryptoProviderTest);
 +
 +		CPPUNIT_TEST(testGetSHA1Hash);
 +		CPPUNIT_TEST(testGetSHA1Hash_TwoUpdates);
 +		CPPUNIT_TEST(testGetSHA1Hash_NoData);
 +		CPPUNIT_TEST(testGetSHA1HashStatic);
 +		CPPUNIT_TEST(testGetSHA1HashStatic_Twice);
 +		CPPUNIT_TEST(testGetSHA1HashStatic_NoData);
 +
 +		CPPUNIT_TEST(testGetMD5Hash_Empty);
 +		CPPUNIT_TEST(testGetMD5Hash_Alphabet);
 +		CPPUNIT_TEST(testMD5Incremental);
 +
 +		CPPUNIT_TEST(testGetHMACSHA1);
 +		CPPUNIT_TEST(testGetHMACSHA1_KeyLongerThanBlockSize);
 +		
 +		CPPUNIT_TEST_SUITE_END();
 +
 +	public:
 +		void setUp() {
 +			provider = new CryptoProviderType();
 +		}
 +
 +		void tearDown() {
 +			delete provider;
 +		}
 +
 +		////////////////////////////////////////////////////////////	
 +		// SHA-1
 +		////////////////////////////////////////////////////////////	
 +		
 +		void testGetSHA1Hash() {
 +			boost::shared_ptr<Hash> sha = boost::shared_ptr<Hash>(provider->createSHA1());
 +			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 testGetSHA1Hash_TwoUpdates() {
 +			boost::shared_ptr<Hash> sha = boost::shared_ptr<Hash>(provider->createSHA1());
 +			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 testGetSHA1Hash_NoData() {
 +			boost::shared_ptr<Hash> sha = boost::shared_ptr<Hash>(provider->createSHA1());
 +			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 testGetSHA1HashStatic() {
 +			ByteArray result(provider->getSHA1Hash(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 testGetSHA1HashStatic_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<"));
 +			provider->getSHA1Hash(input);
 +			ByteArray result(provider->getSHA1Hash(input));
 +
 +			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 testGetSHA1HashStatic_NoData() {
 +			ByteArray result(provider->getSHA1Hash(ByteArray()));
 +
 +			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);
 +		}
 +		
 +		
 +		////////////////////////////////////////////////////////////	
 +		// MD5
 +		////////////////////////////////////////////////////////////	
 +
 +		void testGetMD5Hash_Empty() {
 +			ByteArray result(provider->getMD5Hash(createByteArray("")));
 +
 +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", 16), result);
 +		}
 +
 +		void testGetMD5Hash_Alphabet() {
 +			ByteArray result(provider->getMD5Hash(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")));
 +
 +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result);
 +		}
 +
 +		void testMD5Incremental() {
 +			boost::shared_ptr<Hash> testling = boost::shared_ptr<Hash>(provider->createMD5());
 +			testling->update(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
 +			testling->update(createByteArray("abcdefghijklmnopqrstuvwxyz0123456789"));
 +
 +			ByteArray result = testling->getHash();
 +
 +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result);
 +		}
 +
 +
 +		////////////////////////////////////////////////////////////	
 +		// HMAC-SHA1
 +		////////////////////////////////////////////////////////////	
 +
 +		void testGetHMACSHA1() {
 +			ByteArray result(provider->getHMACSHA1(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 testGetHMACSHA1_KeyLongerThanBlockSize() {
 +			ByteArray result(provider->getHMACSHA1(createSafeByteArray("---------|---------|---------|---------|---------|----------|---------|"), createByteArray("foobar")));
 +			CPPUNIT_ASSERT_EQUAL(createByteArray("\xd6""n""\x8f""P|1""\xd3"",""\x6"" ""\xb9\xe3""gg""\x8e\xcf"" ]+""\xa"), result);
 +		}
 +
 +	private:
 +		CryptoProviderType* provider;
 +};
 +
 +#ifdef SWIFTEN_PLATFORM_WIN32
 +CPPUNIT_TEST_SUITE_REGISTRATION(CryptoProviderTest<WindowsCryptoProvider>);
 +#endif
 +#ifdef HAVE_OPENSSL_CRYPTO_PROVIDER
 +CPPUNIT_TEST_SUITE_REGISTRATION(CryptoProviderTest<OpenSSLCryptoProvider>);
 +#endif
 +#ifdef HAVE_COMMONCRYPTO_CRYPTO_PROVIDER
 +CPPUNIT_TEST_SUITE_REGISTRATION(CryptoProviderTest<CommonCryptoCryptoProvider>);
 +#endif
 diff --git a/Swiften/Crypto/WindowsCryptoProvider.cpp b/Swiften/Crypto/WindowsCryptoProvider.cpp new file mode 100644 index 0000000..7cc6a46 --- /dev/null +++ b/Swiften/Crypto/WindowsCryptoProvider.cpp @@ -0,0 +1,256 @@ +/*
 + * Copyright (c) 2012 Kevin Smith
 + * Licensed under the GNU General Public License.
 + * See the COPYING file for more information.
 + */
 +
 +/*
 + * Copyright (c) 2013 Remko Tronçon
 + * Licensed under the GNU General Public License.
 + * See the COPYING file for more information.
 + */
 +
 +#include <Swiften/Crypto/WindowsCryptoProvider.h>
 +
 +#include <Windows.h>
 +#define SECURITY_WIN32
 +#include <security.h>
 +#include <Wincrypt.h>
 +#include <cassert>
 +#include <boost/smart_ptr/make_shared.hpp>
 +
 +#include <Swiften/Crypto/Hash.h>
 +#include <Swiften/Base/ByteArray.h>
 +#include <Swiften/Base/Algorithm.h>
 +#include <Swiften/Base/WindowsRegistry.h>
 +
 +using namespace Swift;
 +
 +struct WindowsCryptoProvider::Private {
 +	HCRYPTPROV context;
 +};
 +
 +namespace {
 +	class WindowsHash : public Hash {
 +		public:
 +			WindowsHash(HCRYPTPROV context, ALG_ID algorithm) : hash(NULL) {
 +				if (!CryptCreateHash(context, algorithm, 0, 0, &hash)) {
 +					assert(false);
 +				}
 +			}
 +
 +			~WindowsHash() {
 +				CryptDestroyHash(hash);
 +			}
 +
 +			virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE {
 +				return updateInternal(data);
 +			}
 +
 +			virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE {
 +				return updateInternal(data);
 +			}
 +
 +			virtual std::vector<unsigned char> getHash() {
 +				std::vector<unsigned char> result;
 +				DWORD hashLength = sizeof(DWORD);
 +				DWORD hashSize;
 +				CryptGetHashParam(hash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &hashLength, 0);
 +				result.resize(static_cast<size_t>(hashSize));
 +				if (!CryptGetHashParam(hash, HP_HASHVAL, vecptr(result), &hashSize, 0)) {
 +					assert(false);
 +				}
 +				result.resize(static_cast<size_t>(hashSize));
 +				return result;
 +			}
 +
 +		private:
 +			template<typename ContainerType>
 +			Hash& updateInternal(const ContainerType& data) {
 +				if (!CryptHashData(hash, const_cast<BYTE*>(vecptr(data)), data.size(), 0)) {
 +					assert(false);
 +				}
 +				return *this;
 +			}
 +
 +		private:
 +			HCRYPTHASH hash;
 +	};
 +
 +#if 0
 +	// Haven't tested the code below properly yet, but figured out after writing
 +	// it that PLAINTEXTKEYBLOB doesn't work on XP or 2k, and the workaround is a
 +	// bit too ugly to try this now. So, using our own algorithm for now.  See
 +	// http://support.microsoft.com/kb/228786/en-us
 +	
 +	// MSDN describes this as PLAINTEXTKEYBLOB, but this struct doesn't exist,
 +	// and seems to even conflict with the PLAINTEXTKEYBLOB constant. Redefining
 +	// here.
 +	struct PlainTextKeyBlob {
 +		BLOBHEADER hdr;
 +		DWORD dwKeySize;
 +	};
 +
 +	class HMACHash : public Hash {
 +		public:
 +			template<typename T>
 +			HMACHash(HCRYPTPROV context, const T& rawKey) : hash(NULL) {
 +				// Import raw key
 +				T blobData(sizeof(PlainTextKeyBlob) + rawKey.size());
 +				PlainTextKeyBlob* blob = reinterpret_cast<PlainTextKeyBlob*>(vecptr(blobData));
 +				blob->hdr.bType = PLAINTEXTKEYBLOB;
 +				blob->hdr.bVersion = CUR_BLOB_VERSION;
 +				blob->hdr.reserved = 0;
 +				blob->hdr.aiKeyAlg = CALG_RC2;
 +				blob->dwKeySize = rawKey.size();
 +				std::copy(rawKey.begin(), rawKey.end(), blobData.begin() + sizeof(PlainTextKeyBlob));
 +				HCRYPTKEY key;
 +				if (!CryptImportKey(context, vecptr(blobData), blobData.size(), 0, CRYPT_IPSEC_HMAC_KEY, &key)) {
 +					assert(false);
 +					return;
 +				}
 +
 +				// Create hash
 +				if (!CryptCreateHash(context, CALG_HMAC, key, 0, &hash)) {
 +					assert(false);
 +					return;
 +				}
 +				ZeroMemory(&info, sizeof(info));
 +				info.HashAlgid = CALG_SHA1;
 +			}
 +
 +			~HMACHash() {
 +				CryptDestroyHash(hash);
 +			}
 +
 +			virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE {
 +				return updateInternal(data);
 +			}
 +
 +			virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE {
 +				return updateInternal(data);
 +			}
 +
 +			virtual std::vector<unsigned char> getHash() {
 +				std::vector<unsigned char> result;
 +				DWORD hashLength = sizeof(DWORD);
 +				DWORD hashSize;
 +				CryptGetHashParam(hash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &hashLength, 0);
 +				result.resize(static_cast<size_t>(hashSize));
 +				if (!CryptGetHashParam(hash, HP_HASHVAL, vecptr(result), &hashSize, 0)) {
 +					assert(false);
 +				}
 +				result.resize(static_cast<size_t>(hashSize));
 +				return result;
 +			}
 +
 +		private:
 +			template<typename ContainerType>
 +			Hash& updateInternal(const ContainerType& data) {
 +				if (!CryptHashData(hash, const_cast<BYTE*>(vecptr(data)), data.size(), 0)) {
 +					assert(false);
 +				}
 +				return *this;
 +			}
 +
 +		private:
 +			HCRYPTHASH hash;
 +			HMAC_INFO info;
 +	};
 +#endif
 +
 +	// Simple implementation. You can only call 'update' once.
 +	template<typename T>
 +	class HMACHash : public Hash {
 +		public:
 +			HMACHash(const T& key, CryptoProvider* crypto) : crypto(crypto), finished(false) {
 +				if (key.size() <= BLOCK_SIZE) {
 +					paddedKey = key;
 +				}
 +				else {
 +					assign(paddedKey, crypto->getSHA1Hash(key));
 +				}
 +				paddedKey.resize(BLOCK_SIZE, 0x0);
 +			}
 +
 +			~HMACHash() {
 +			}
 +
 +			virtual Hash& update(const ByteArray& data) SWIFTEN_OVERRIDE {
 +				return updateInternal(data);
 +			}
 +
 +			virtual Hash& update(const SafeByteArray& data) SWIFTEN_OVERRIDE {
 +				return updateInternal(data);
 +			}
 +
 +			virtual std::vector<unsigned char> getHash() {
 +				return result;
 +			}
 +
 +		private:
 +			template<typename ContainerType>
 +			Hash& updateInternal(const ContainerType& data) {
 +				assert(!finished);
 +
 +				// Create the first value
 +				T x(paddedKey);
 +				for (unsigned int i = 0; i < x.size(); ++i) {
 +					x[i] ^= 0x36;
 +				}
 +				append(x, data);
 +
 +				// Create the second value
 +				T y(paddedKey);
 +				for (unsigned int i = 0; i < y.size(); ++i) {
 +					y[i] ^= 0x5c;
 +				}
 +				append(y, crypto->getSHA1Hash(x));
 +				result = crypto->getSHA1Hash(y);
 +
 +				finished = true;
 +				return *this;
 +			}
 +
 +		private:
 +			static const int BLOCK_SIZE = 64;
 +			CryptoProvider* crypto;
 +			T paddedKey;
 +			SafeByteArray data;
 +			bool finished;
 +			std::vector<unsigned char> result;
 +	};
 +
 +
 +}
 +
 +WindowsCryptoProvider::WindowsCryptoProvider() {
 +	p = boost::make_shared<Private>();
 +	if (!CryptAcquireContext(&p->context, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
 +		assert(false);
 +	}
 +}
 +
 +WindowsCryptoProvider::~WindowsCryptoProvider() {
 +	CryptReleaseContext(p->context, 0);
 +}
 +
 +Hash* WindowsCryptoProvider::createSHA1() {
 +	return new WindowsHash(p->context, CALG_SHA1);
 +}
 +
 +Hash* WindowsCryptoProvider::createMD5() {
 +	return new WindowsHash(p->context, CALG_MD5);
 +}
 +
 +bool WindowsCryptoProvider::isMD5AllowedForCrypto() const {
 +	return !WindowsRegistry::isFIPSEnabled();
 +}
 +
 +Hash* WindowsCryptoProvider::createHMACSHA1(const SafeByteArray& key) {
 +	return new HMACHash<SafeByteArray>(key, this);
 +}
 +
 +Hash* WindowsCryptoProvider::createHMACSHA1(const ByteArray& key) {
 +	return new HMACHash<ByteArray>(key, this);
 +}
 diff --git a/Swiften/Crypto/WindowsCryptoProvider.h b/Swiften/Crypto/WindowsCryptoProvider.h new file mode 100644 index 0000000..242d4c2 --- /dev/null +++ b/Swiften/Crypto/WindowsCryptoProvider.h @@ -0,0 +1,30 @@ +/*
 + * Copyright (c) 2013  Remko Tronçon
 + * Licensed under the GNU General Public License.
 + * See the COPYING file for more information.
 + */
 +
 +#pragma once
 +
 +#include <Swiften/Crypto/CryptoProvider.h>
 +#include <Swiften/Base/Override.h>
 +#include <boost/noncopyable.hpp>
 +#include <boost/shared_ptr.hpp>
 +
 +namespace Swift {
 +	class WindowsCryptoProvider : public CryptoProvider, public boost::noncopyable {
 +		public:
 +			WindowsCryptoProvider();
 +			~WindowsCryptoProvider();
 +
 +			virtual Hash* createSHA1() SWIFTEN_OVERRIDE;
 +			virtual Hash* createMD5() SWIFTEN_OVERRIDE;
 +			virtual Hash* createHMACSHA1(const SafeByteArray& key) SWIFTEN_OVERRIDE;
 +			virtual Hash* createHMACSHA1(const ByteArray& key) SWIFTEN_OVERRIDE;
 +			virtual bool isMD5AllowedForCrypto() const SWIFTEN_OVERRIDE;
 +
 +		private:
 +			struct Private;
 +			boost::shared_ptr<Private> p;
 +	};
 +}
 diff --git a/Swiften/Disco/CapsInfoGenerator.cpp b/Swiften/Disco/CapsInfoGenerator.cpp index 6d84984..cb93182 100644 --- a/Swiften/Disco/CapsInfoGenerator.cpp +++ b/Swiften/Disco/CapsInfoGenerator.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -11,7 +11,7 @@  #include <Swiften/Base/foreach.h>  #include <Swiften/Elements/DiscoInfo.h>  #include <Swiften/Elements/FormField.h> -#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/Crypto/CryptoProvider.h>  #include <Swiften/StringCodecs/Base64.h>  namespace { @@ -22,7 +22,7 @@ namespace {  namespace Swift { -CapsInfoGenerator::CapsInfoGenerator(const std::string& node) : node_(node) { +CapsInfoGenerator::CapsInfoGenerator(const std::string& node, CryptoProvider* crypto) : node_(node), crypto_(crypto) {  }  CapsInfo CapsInfoGenerator::generateCapsInfo(const DiscoInfo& discoInfo) const { @@ -57,7 +57,7 @@ CapsInfo CapsInfoGenerator::generateCapsInfo(const DiscoInfo& discoInfo) const {  		}  	} -	std::string version(Base64::encode(SHA1::getHash(createByteArray(serializedCaps)))); +	std::string version(Base64::encode(crypto_->getSHA1Hash(createByteArray(serializedCaps))));  	return CapsInfo(node_, version, "sha-1");  } diff --git a/Swiften/Disco/CapsInfoGenerator.h b/Swiften/Disco/CapsInfoGenerator.h index 62958e7..17a01dd 100644 --- a/Swiften/Disco/CapsInfoGenerator.h +++ b/Swiften/Disco/CapsInfoGenerator.h @@ -12,14 +12,16 @@  namespace Swift {  	class DiscoInfo; +	class CryptoProvider;  	class SWIFTEN_API CapsInfoGenerator {  		public: -			CapsInfoGenerator(const std::string& node); +			CapsInfoGenerator(const std::string& node, CryptoProvider* crypto);  			CapsInfo generateCapsInfo(const DiscoInfo& discoInfo) const;  		private:  			std::string node_; +			CryptoProvider* crypto_;  	};  } diff --git a/Swiften/Disco/CapsManager.cpp b/Swiften/Disco/CapsManager.cpp index 66eb47e..18f8745 100644 --- a/Swiften/Disco/CapsManager.cpp +++ b/Swiften/Disco/CapsManager.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -17,7 +17,7 @@  namespace Swift { -CapsManager::CapsManager(CapsStorage* capsStorage, StanzaChannel* stanzaChannel, IQRouter* iqRouter) : iqRouter(iqRouter), capsStorage(capsStorage), warnOnInvalidHash(true) { +CapsManager::CapsManager(CapsStorage* capsStorage, StanzaChannel* stanzaChannel, IQRouter* iqRouter, CryptoProvider* crypto) : iqRouter(iqRouter), crypto(crypto), capsStorage(capsStorage), warnOnInvalidHash(true) {  	stanzaChannel->onPresenceReceived.connect(boost::bind(&CapsManager::handlePresenceReceived, this, _1));  	stanzaChannel->onAvailableChanged.connect(boost::bind(&CapsManager::handleStanzaChannelAvailableChanged, this, _1));  } @@ -51,7 +51,7 @@ void CapsManager::handleStanzaChannelAvailableChanged(bool available) {  void CapsManager::handleDiscoInfoReceived(const JID& from, const std::string& hash, DiscoInfo::ref discoInfo, ErrorPayload::ref error) {  	requestedDiscoInfos.erase(hash); -	if (error || !discoInfo || CapsInfoGenerator("").generateCapsInfo(*discoInfo.get()).getVersion() != hash) { +	if (error || !discoInfo || CapsInfoGenerator("", crypto).generateCapsInfo(*discoInfo.get()).getVersion() != hash) {  		if (warnOnInvalidHash && !error &&  discoInfo) {  			std::cerr << "Warning: Caps from " << from.toString() << " do not verify" << std::endl;  		} diff --git a/Swiften/Disco/CapsManager.h b/Swiften/Disco/CapsManager.h index 9f1d83b..3529812 100644 --- a/Swiften/Disco/CapsManager.h +++ b/Swiften/Disco/CapsManager.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -22,10 +22,11 @@ namespace Swift {  	class IQRouter;  	class JID;  	class CapsStorage; +	class CryptoProvider;  	class SWIFTEN_API CapsManager : public CapsProvider, public boost::bsignals::trackable {   		public: -			CapsManager(CapsStorage*, StanzaChannel*, IQRouter*); +			CapsManager(CapsStorage*, StanzaChannel*, IQRouter*, CryptoProvider*);  			DiscoInfo::ref getCaps(const std::string&) const; @@ -42,6 +43,7 @@ namespace Swift {  		private:  			IQRouter* iqRouter; +			CryptoProvider* crypto;  			CapsStorage* capsStorage;  			bool warnOnInvalidHash;  			std::set<std::string> requestedDiscoInfos; diff --git a/Swiften/Disco/ClientDiscoManager.cpp b/Swiften/Disco/ClientDiscoManager.cpp index cca0144..f6683a8 100644 --- a/Swiften/Disco/ClientDiscoManager.cpp +++ b/Swiften/Disco/ClientDiscoManager.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -12,7 +12,7 @@  namespace Swift { -ClientDiscoManager::ClientDiscoManager(IQRouter* iqRouter, PresenceSender* presenceSender) { +ClientDiscoManager::ClientDiscoManager(IQRouter* iqRouter, PresenceSender* presenceSender, CryptoProvider* crypto) : crypto(crypto) {  	discoInfoResponder = new DiscoInfoResponder(iqRouter);  	discoInfoResponder->start();  	this->presenceSender = new PayloadAddingPresenceSender(presenceSender); @@ -29,7 +29,7 @@ void ClientDiscoManager::setCapsNode(const std::string& node) {  }  void ClientDiscoManager::setDiscoInfo(const DiscoInfo& discoInfo) { -	capsInfo = CapsInfo::ref(new CapsInfo(CapsInfoGenerator(capsNode).generateCapsInfo(discoInfo))); +	capsInfo = CapsInfo::ref(new CapsInfo(CapsInfoGenerator(capsNode, crypto).generateCapsInfo(discoInfo)));  	discoInfoResponder->clearDiscoInfo();  	discoInfoResponder->setDiscoInfo(discoInfo);  	discoInfoResponder->setDiscoInfo(capsInfo->getNode() + "#" + capsInfo->getVersion(), discoInfo); diff --git a/Swiften/Disco/ClientDiscoManager.h b/Swiften/Disco/ClientDiscoManager.h index 0cae40e..a9ed10a 100644 --- a/Swiften/Disco/ClientDiscoManager.h +++ b/Swiften/Disco/ClientDiscoManager.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -16,6 +16,7 @@ namespace Swift {  	class DiscoInfoResponder;  	class PayloadAddingPresenceSender;  	class PresenceSender; +	class CryptoProvider;  	/**  	 * Class responsible for managing outgoing disco information for a client. @@ -36,7 +37,7 @@ namespace Swift {  			 * \param presenceSender the presence sender to which all outgoing presence  			 *   (with caps information) will be sent.  			 */ -			ClientDiscoManager(IQRouter* iqRouter, PresenceSender* presenceSender); +			ClientDiscoManager(IQRouter* iqRouter, PresenceSender* presenceSender, CryptoProvider* crypto);  			~ClientDiscoManager();  			/** @@ -68,6 +69,7 @@ namespace Swift {  		private:  			PayloadAddingPresenceSender* presenceSender; +			CryptoProvider* crypto;  			DiscoInfoResponder* discoInfoResponder;  			std::string capsNode;  			CapsInfo::ref capsInfo; diff --git a/Swiften/Disco/UnitTest/CapsInfoGeneratorTest.cpp b/Swiften/Disco/UnitTest/CapsInfoGeneratorTest.cpp index 52fdbaa..a1b1a7b 100644 --- a/Swiften/Disco/UnitTest/CapsInfoGeneratorTest.cpp +++ b/Swiften/Disco/UnitTest/CapsInfoGeneratorTest.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -9,6 +9,8 @@  #include <Swiften/Elements/DiscoInfo.h>  #include <Swiften/Disco/CapsInfoGenerator.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -19,6 +21,10 @@ class CapsInfoGeneratorTest : public CppUnit::TestFixture {  		CPPUNIT_TEST_SUITE_END();  	public: +		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); +		} +  		void testGenerate_XEP0115SimpleExample() {  			DiscoInfo discoInfo;  			discoInfo.addIdentity(DiscoInfo::Identity("Exodus 0.9.1", "client", "pc")); @@ -27,7 +33,7 @@ class CapsInfoGeneratorTest : public CppUnit::TestFixture {  			discoInfo.addFeature("http://jabber.org/protocol/disco#info");  			discoInfo.addFeature("http://jabber.org/protocol/muc"); -			CapsInfoGenerator testling("http://code.google.com/p/exodus"); +			CapsInfoGenerator testling("http://code.google.com/p/exodus", crypto.get());  			CapsInfo result = testling.generateCapsInfo(discoInfo);  			CPPUNIT_ASSERT_EQUAL(std::string("http://code.google.com/p/exodus"), result.getNode()); @@ -74,11 +80,14 @@ class CapsInfoGeneratorTest : public CppUnit::TestFixture {  			extension->addField(field);  			discoInfo.addExtension(extension); -			CapsInfoGenerator testling("http://psi-im.org"); +			CapsInfoGenerator testling("http://psi-im.org", crypto.get());  			CapsInfo result = testling.generateCapsInfo(discoInfo);  			CPPUNIT_ASSERT_EQUAL(std::string("q07IKJEyjvHSyhy//CH0CxmKi8w="), result.getVersion());  		} +		 +	private: +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(CapsInfoGeneratorTest); diff --git a/Swiften/Disco/UnitTest/CapsManagerTest.cpp b/Swiften/Disco/UnitTest/CapsManagerTest.cpp index ca55c48..303fd78 100644 --- a/Swiften/Disco/UnitTest/CapsManagerTest.cpp +++ b/Swiften/Disco/UnitTest/CapsManagerTest.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -16,6 +16,8 @@  #include <Swiften/Elements/CapsInfo.h>  #include <Swiften/Elements/DiscoInfo.h>  #include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -41,18 +43,19 @@ class CapsManagerTest : public CppUnit::TestFixture {  	public:  		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());  			stanzaChannel = new DummyStanzaChannel();  			iqRouter = new IQRouter(stanzaChannel);  			storage = new CapsMemoryStorage();  			user1 = JID("user1@bar.com/bla");  			discoInfo1 = boost::make_shared<DiscoInfo>();  			discoInfo1->addFeature("http://swift.im/feature1"); -			capsInfo1 = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node1.im").generateCapsInfo(*discoInfo1.get())); -			capsInfo1alt = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node2.im").generateCapsInfo(*discoInfo1.get())); +			capsInfo1 = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node1.im", crypto.get()).generateCapsInfo(*discoInfo1.get())); +			capsInfo1alt = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node2.im", crypto.get()).generateCapsInfo(*discoInfo1.get()));  			user2 = JID("user2@foo.com/baz");  			discoInfo2 = boost::make_shared<DiscoInfo>();  			discoInfo2->addFeature("http://swift.im/feature2"); -			capsInfo2 = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node2.im").generateCapsInfo(*discoInfo2.get())); +			capsInfo2 = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node2.im", crypto.get()).generateCapsInfo(*discoInfo2.get()));  			user3 = JID("user3@foo.com/baz");  			legacyCapsInfo = boost::make_shared<CapsInfo>("http://swift.im", "ver1", "");  		} @@ -246,7 +249,7 @@ class CapsManagerTest : public CppUnit::TestFixture {  	private:  		boost::shared_ptr<CapsManager> createManager() { -			boost::shared_ptr<CapsManager> manager(new CapsManager(storage, stanzaChannel, iqRouter)); +			boost::shared_ptr<CapsManager> manager(new CapsManager(storage, stanzaChannel, iqRouter, crypto.get()));  			manager->setWarnOnInvalidHash(false);  			//manager->onCapsChanged.connect(boost::bind(&CapsManagerTest::handleCapsChanged, this, _1));  			return manager; @@ -281,6 +284,7 @@ class CapsManagerTest : public CppUnit::TestFixture {  		boost::shared_ptr<CapsInfo> capsInfo2;  		boost::shared_ptr<CapsInfo> legacyCapsInfo;  		JID user3; +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(CapsManagerTest); diff --git a/Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp b/Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp index 0fd966d..940f043 100644 --- a/Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp +++ b/Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -14,6 +14,8 @@  #include <Swiften/Elements/CapsInfo.h>  #include <Swiften/Client/DummyStanzaChannel.h>  #include <Swiften/Disco/CapsInfoGenerator.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -30,18 +32,20 @@ class EntityCapsManagerTest : public CppUnit::TestFixture {  	public:  		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); +  			stanzaChannel = new DummyStanzaChannel();  			capsProvider = new DummyCapsProvider();  			user1 = JID("user1@bar.com/bla");  			discoInfo1 = boost::make_shared<DiscoInfo>();  			discoInfo1->addFeature("http://swift.im/feature1"); -			capsInfo1 = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node1.im").generateCapsInfo(*discoInfo1.get())); -			capsInfo1alt = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node2.im").generateCapsInfo(*discoInfo1.get())); +			capsInfo1 = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node1.im", crypto.get()).generateCapsInfo(*discoInfo1.get())); +			capsInfo1alt = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node2.im", crypto.get()).generateCapsInfo(*discoInfo1.get()));  			user2 = JID("user2@foo.com/baz");  			discoInfo2 = boost::make_shared<DiscoInfo>();  			discoInfo2->addFeature("http://swift.im/feature2"); -			capsInfo2 = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node2.im").generateCapsInfo(*discoInfo2.get())); +			capsInfo2 = boost::make_shared<CapsInfo>(CapsInfoGenerator("http://node2.im", crypto.get()).generateCapsInfo(*discoInfo2.get()));  			user3 = JID("user3@foo.com/baz");  			legacyCapsInfo = boost::make_shared<CapsInfo>("http://swift.im", "ver1", "");  		} @@ -183,6 +187,7 @@ class EntityCapsManagerTest : public CppUnit::TestFixture {  		boost::shared_ptr<CapsInfo> legacyCapsInfo;  		JID user3;  		std::vector<JID> changes; +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(EntityCapsManagerTest); diff --git a/Swiften/Examples/SendFile/SendFile.cpp b/Swiften/Examples/SendFile/SendFile.cpp index 39a8603..1e4fc14 100644 --- a/Swiften/Examples/SendFile/SendFile.cpp +++ b/Swiften/Examples/SendFile/SendFile.cpp @@ -29,8 +29,6 @@  #include <Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h>  #include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h>  #include <Swiften/Base/ByteArray.h> -#include <Swiften/StringCodecs/MD5.h> -#include <Swiften/StringCodecs/SHA1.h>  #include <Swiften/StringCodecs/Hexify.h>  #include <Swiften/FileTransfer/FileTransferManager.h> diff --git a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.cpp b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.cpp index 4a6b61f..40b23d2 100644 --- a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.cpp +++ b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.cpp @@ -4,6 +4,12 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.h>  #include <boost/smart_ptr/make_shared.hpp> @@ -18,7 +24,7 @@  namespace Swift { -DefaultRemoteJingleTransportCandidateSelector::DefaultRemoteJingleTransportCandidateSelector(ConnectionFactory* connectionFactory, TimerFactory* timerFactory) : connectionFactory(connectionFactory), timerFactory(timerFactory) { +DefaultRemoteJingleTransportCandidateSelector::DefaultRemoteJingleTransportCandidateSelector(ConnectionFactory* connectionFactory, TimerFactory* timerFactory, CryptoProvider* crypto) : connectionFactory(connectionFactory), timerFactory(timerFactory), crypto(crypto) {  }  DefaultRemoteJingleTransportCandidateSelector::~DefaultRemoteJingleTransportCandidateSelector() { @@ -58,7 +64,7 @@ void DefaultRemoteJingleTransportCandidateSelector::tryNextCandidate(bool error)  				lastCandidate.type == JingleS5BTransportPayload::Candidate::AssistedType || lastCandidate.type == JingleS5BTransportPayload::Candidate::ProxyType ) {  				// create connection  				connection = connectionFactory->createConnection(); -				s5bSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, lastCandidate.hostPort, SOCKS5BytestreamRegistry::getHostname(transportSID, requester, target), timerFactory); +				s5bSession = boost::make_shared<SOCKS5BytestreamClientSession>(connection, lastCandidate.hostPort, SOCKS5BytestreamRegistry::getHostname(transportSID, requester, target, crypto), timerFactory);  				// bind onReady to this method  				s5bSession->onSessionReady.connect(boost::bind(&DefaultRemoteJingleTransportCandidateSelector::tryNextCandidate, this, _1)); diff --git a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.h b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.h index 073c51f..13e8cd6 100644 --- a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.h +++ b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.h @@ -4,6 +4,12 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #pragma once  #include <queue> @@ -23,10 +29,11 @@ namespace Swift {  class ConnectionFactory;  class TimerFactory; +class CryptoProvider;  class DefaultRemoteJingleTransportCandidateSelector : public RemoteJingleTransportCandidateSelector {  public: -	DefaultRemoteJingleTransportCandidateSelector(ConnectionFactory*, TimerFactory*); +	DefaultRemoteJingleTransportCandidateSelector(ConnectionFactory*, TimerFactory*, CryptoProvider*);  	virtual ~DefaultRemoteJingleTransportCandidateSelector();  	virtual void addRemoteTransportCandidates(JingleTransportPayload::ref) SWIFTEN_OVERRIDE; @@ -45,6 +52,7 @@ private:  private:  	ConnectionFactory* connectionFactory;  	TimerFactory* timerFactory; +	CryptoProvider* crypto;  	std::priority_queue<JingleS5BTransportPayload::Candidate, std::vector<JingleS5BTransportPayload::Candidate>, JingleS5BTransportPayload::CompareCandidate> candidates; diff --git a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.cpp b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.cpp index 8ebbf46..5fcdf79 100644 --- a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.cpp +++ b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.cpp @@ -4,6 +4,12 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #include "DefaultRemoteJingleTransportCandidateSelectorFactory.h"  #include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelector.h> @@ -12,14 +18,14 @@  namespace Swift { -DefaultRemoteJingleTransportCandidateSelectorFactory::DefaultRemoteJingleTransportCandidateSelectorFactory(ConnectionFactory* connectionFactory, TimerFactory* timerFactory) : connectionFactory(connectionFactory), timerFactory(timerFactory) { +DefaultRemoteJingleTransportCandidateSelectorFactory::DefaultRemoteJingleTransportCandidateSelectorFactory(ConnectionFactory* connectionFactory, TimerFactory* timerFactory, CryptoProvider* crypto) : connectionFactory(connectionFactory), timerFactory(timerFactory), crypto(crypto) {  }  DefaultRemoteJingleTransportCandidateSelectorFactory::~DefaultRemoteJingleTransportCandidateSelectorFactory() {  }  RemoteJingleTransportCandidateSelector* DefaultRemoteJingleTransportCandidateSelectorFactory::createCandidateSelector() { -	return new DefaultRemoteJingleTransportCandidateSelector(connectionFactory, timerFactory); +	return new DefaultRemoteJingleTransportCandidateSelector(connectionFactory, timerFactory, crypto);  }  } diff --git a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h index ca29e1f..19f8c38 100644 --- a/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h +++ b/Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h @@ -4,6 +4,12 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #pragma once  #include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h> @@ -12,10 +18,11 @@ namespace Swift {  class ConnectionFactory;  class TimerFactory; +class CryptoProvider;  class DefaultRemoteJingleTransportCandidateSelectorFactory : public RemoteJingleTransportCandidateSelectorFactory {  public: -	DefaultRemoteJingleTransportCandidateSelectorFactory(ConnectionFactory*, TimerFactory*); +	DefaultRemoteJingleTransportCandidateSelectorFactory(ConnectionFactory*, TimerFactory*, CryptoProvider*);  	virtual ~DefaultRemoteJingleTransportCandidateSelectorFactory();  	RemoteJingleTransportCandidateSelector* createCandidateSelector(); @@ -23,6 +30,7 @@ public:  private:  	ConnectionFactory* connectionFactory;  	TimerFactory* timerFactory; +	CryptoProvider* crypto;  };  } diff --git a/Swiften/FileTransfer/FileTransferManagerImpl.cpp b/Swiften/FileTransfer/FileTransferManagerImpl.cpp index d5d4aaf..b80ad9a 100644 --- a/Swiften/FileTransfer/FileTransferManagerImpl.cpp +++ b/Swiften/FileTransfer/FileTransferManagerImpl.cpp @@ -4,6 +4,12 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #include <Swiften/FileTransfer/FileTransferManagerImpl.h>  #include <boost/bind.hpp> @@ -35,7 +41,7 @@  namespace Swift { -FileTransferManagerImpl::FileTransferManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, PresenceOracle* presOracle, ConnectionFactory* connectionFactory, ConnectionServerFactory* connectionServerFactory, TimerFactory* timerFactory, NATTraverser* natTraverser) : ownJID(ownFullJID), jingleSM(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), presenceOracle(presOracle), connectionServerFactory(connectionServerFactory), bytestreamServer(NULL), s5bProxyFinder(NULL) { +FileTransferManagerImpl::FileTransferManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, PresenceOracle* presOracle, ConnectionFactory* connectionFactory, ConnectionServerFactory* connectionServerFactory, TimerFactory* timerFactory, NATTraverser* natTraverser, CryptoProvider* crypto) : ownJID(ownFullJID), jingleSM(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), presenceOracle(presOracle), connectionServerFactory(connectionServerFactory), crypto(crypto), bytestreamServer(NULL), s5bProxyFinder(NULL) {  	assert(!ownFullJID.isBare());  	connectivityManager = new ConnectivityManager(natTraverser); @@ -43,9 +49,9 @@ FileTransferManagerImpl::FileTransferManagerImpl(const JID& ownFullJID, JingleSe  	bytestreamProxy = new SOCKS5BytestreamProxy(connectionFactory, timerFactory);  	localCandidateGeneratorFactory = new DefaultLocalJingleTransportCandidateGeneratorFactory(connectivityManager, bytestreamRegistry, bytestreamProxy, ownFullJID); -	remoteCandidateSelectorFactory = new DefaultRemoteJingleTransportCandidateSelectorFactory(connectionFactory, timerFactory); -	outgoingFTManager = new OutgoingFileTransferManager(jingleSM, iqRouter, capsProvider, remoteCandidateSelectorFactory, localCandidateGeneratorFactory, bytestreamRegistry, bytestreamProxy); -	incomingFTManager = new IncomingFileTransferManager(jingleSM, iqRouter, remoteCandidateSelectorFactory, localCandidateGeneratorFactory, bytestreamRegistry, bytestreamProxy, timerFactory); +	remoteCandidateSelectorFactory = new DefaultRemoteJingleTransportCandidateSelectorFactory(connectionFactory, timerFactory, crypto); +	outgoingFTManager = new OutgoingFileTransferManager(jingleSM, iqRouter, capsProvider, remoteCandidateSelectorFactory, localCandidateGeneratorFactory, bytestreamRegistry, bytestreamProxy, crypto); +	incomingFTManager = new IncomingFileTransferManager(jingleSM, iqRouter, remoteCandidateSelectorFactory, localCandidateGeneratorFactory, bytestreamRegistry, bytestreamProxy, timerFactory, crypto);  	incomingFTManager->onIncomingFileTransfer.connect(onIncomingFileTransfer);  } @@ -70,7 +76,7 @@ void FileTransferManagerImpl::startListeningOnPort(int port) {  	SWIFT_LOG(debug) << "Start listening on port " << port << " and hope it's not in use." << std::endl;  	boost::shared_ptr<ConnectionServer> server = connectionServerFactory->createConnectionServer(HostAddress("0.0.0.0"), port);  	server->start(); -	bytestreamServer = new SOCKS5BytestreamServer(server, bytestreamRegistry); +	bytestreamServer = new SOCKS5BytestreamServer(server, bytestreamRegistry, crypto);  	bytestreamServer->start();  	connectivityManager->addListeningPort(port); diff --git a/Swiften/FileTransfer/FileTransferManagerImpl.h b/Swiften/FileTransfer/FileTransferManagerImpl.h index 0bbbf31..d5ef144 100644 --- a/Swiften/FileTransfer/FileTransferManagerImpl.h +++ b/Swiften/FileTransfer/FileTransferManagerImpl.h @@ -4,6 +4,12 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #pragma once  #include <vector> @@ -40,10 +46,11 @@ namespace Swift {  	class SOCKS5BytestreamProxy;  	class TimerFactory;  	class SOCKS5BytestreamProxyFinder; +	class CryptoProvider;  	class FileTransferManagerImpl : public FileTransferManager {  		public: -			FileTransferManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, PresenceOracle* presOracle, ConnectionFactory* connectionFactory, ConnectionServerFactory* connectionServerFactory, TimerFactory* timerFactory, NATTraverser* natTraverser); +			FileTransferManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, PresenceOracle* presOracle, ConnectionFactory* connectionFactory, ConnectionServerFactory* connectionServerFactory, TimerFactory* timerFactory, NATTraverser* natTraverser, CryptoProvider* crypto);  			~FileTransferManagerImpl();  			void startListeningOnPort(int port); @@ -68,6 +75,7 @@ namespace Swift {  			PresenceOracle* presenceOracle;  			ConnectionServerFactory* connectionServerFactory; +			CryptoProvider* crypto;  			SOCKS5BytestreamRegistry* bytestreamRegistry;  			SOCKS5BytestreamServer* bytestreamServer;  			SOCKS5BytestreamProxy* bytestreamProxy; diff --git a/Swiften/FileTransfer/IncomingFileTransferManager.cpp b/Swiften/FileTransfer/IncomingFileTransferManager.cpp index 22e8bf9..9bde8e8 100644 --- a/Swiften/FileTransfer/IncomingFileTransferManager.cpp +++ b/Swiften/FileTransfer/IncomingFileTransferManager.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -20,7 +20,7 @@ namespace Swift {  IncomingFileTransferManager::IncomingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router,  							RemoteJingleTransportCandidateSelectorFactory* remoteFactory, -														 LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, TimerFactory* timerFactory) : jingleSessionManager(jingleSessionManager), router(router), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), timerFactory(timerFactory) { +														 LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, TimerFactory* timerFactory, CryptoProvider* crypto) : jingleSessionManager(jingleSessionManager), router(router), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), timerFactory(timerFactory), crypto(crypto) {  	jingleSessionManager->addIncomingSessionHandler(this);  } @@ -35,7 +35,7 @@ bool IncomingFileTransferManager::handleIncomingJingleSession(JingleSession::ref  			JingleFileTransferDescription::ref description = content->getDescription<JingleFileTransferDescription>();  			if (description && description->getOffers().size() == 1) { -				IncomingJingleFileTransfer::ref transfer = boost::make_shared<IncomingJingleFileTransfer>(recipient, session, content, remoteFactory, localFactory, router, bytestreamRegistry, bytestreamProxy, timerFactory); +				IncomingJingleFileTransfer::ref transfer = boost::shared_ptr<IncomingJingleFileTransfer>(new IncomingJingleFileTransfer(recipient, session, content, remoteFactory, localFactory, router, bytestreamRegistry, bytestreamProxy, timerFactory, crypto));  				onIncomingFileTransfer(transfer);  			} else {  				std::cerr << "Received a file-transfer request with no description or more than one file!" << std::endl; diff --git a/Swiften/FileTransfer/IncomingFileTransferManager.h b/Swiften/FileTransfer/IncomingFileTransferManager.h index 2d1c07f..d7b5ae2 100644 --- a/Swiften/FileTransfer/IncomingFileTransferManager.h +++ b/Swiften/FileTransfer/IncomingFileTransferManager.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -20,10 +20,11 @@ namespace Swift {  	class SOCKS5BytestreamRegistry;  	class SOCKS5BytestreamProxy;  	class TimerFactory; +	class CryptoProvider;  	class IncomingFileTransferManager : public IncomingJingleSessionHandler {  		public: -			IncomingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, TimerFactory* timerFactory); +			IncomingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, TimerFactory* timerFactory, CryptoProvider* crypto);  			~IncomingFileTransferManager();  			boost::signal<void (IncomingFileTransfer::ref)> onIncomingFileTransfer; @@ -39,5 +40,6 @@ namespace Swift {  			SOCKS5BytestreamRegistry* bytestreamRegistry;  			SOCKS5BytestreamProxy* bytestreamProxy;  			TimerFactory* timerFactory; +			CryptoProvider* crypto;  	};  } diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp index 0d576ac..6dc53fb 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp @@ -37,11 +37,13 @@ IncomingJingleFileTransfer::IncomingJingleFileTransfer(  		IQRouter* router,  		SOCKS5BytestreamRegistry* registry,  		SOCKS5BytestreamProxy* proxy, -		TimerFactory* timerFactory) : +		TimerFactory* timerFactory, +		CryptoProvider* crypto) :  			ourJID(ourJID),  			session(session),  			router(router),  			initialContent(content), +			crypto(crypto),  			state(Initial),  			receivedBytes(0),  			s5bRegistry(registry), @@ -93,7 +95,7 @@ void IncomingJingleFileTransfer::accept(WriteBytestream::ref stream) {  	assert(!this->stream);  	this->stream = stream; -	hashCalculator = new IncrementalBytestreamHashCalculator( algo == "md5" || hash.empty() , algo == "sha-1" || hash.empty() ); +	hashCalculator = new IncrementalBytestreamHashCalculator( algo == "md5" || hash.empty() , algo == "sha-1" || hash.empty(), crypto);  	stream->onWrite.connect(boost::bind(&IncrementalBytestreamHashCalculator::feedData, hashCalculator, _1));  	stream->onWrite.connect(boost::bind(&IncomingJingleFileTransfer::handleWriteStreamDataReceived, this, _1));  	onStateChange(FileTransfer::State(FileTransfer::State::Negotiating)); @@ -106,7 +108,7 @@ void IncomingJingleFileTransfer::accept(WriteBytestream::ref stream) {  		SWIFT_LOG(debug) << "Got S5B transport payload!" << std::endl;  		state = CreatingInitialTransports;  		s5bSessionID = s5bTransport->getSessionID().empty() ? idGenerator.generateID() : s5bTransport->getSessionID(); -		s5bDestination = SOCKS5BytestreamRegistry::getHostname(s5bSessionID, ourJID, session->getInitiator()); +		s5bDestination = SOCKS5BytestreamRegistry::getHostname(s5bSessionID, ourJID, session->getInitiator(), crypto);  		s5bRegistry->addWriteBytestream(s5bDestination, stream);  		fillCandidateMap(theirCandidates, s5bTransport);  		candidateSelector->addRemoteTransportCandidates(s5bTransport); @@ -329,7 +331,7 @@ void IncomingJingleFileTransfer::useTheirCandidateChoiceForTransfer(JingleS5BTra  	if (candidate.type == JingleS5BTransportPayload::Candidate::ProxyType) {  		// get proxy client session from s5bRegistry -		clientSession = s5bProxy->createSOCKS5BytestreamClientSession(candidate.hostPort, SOCKS5BytestreamRegistry::getHostname(s5bSessionID, ourJID, session->getInitiator())); +		clientSession = s5bProxy->createSOCKS5BytestreamClientSession(candidate.hostPort, SOCKS5BytestreamRegistry::getHostname(s5bSessionID, ourJID, session->getInitiator(), crypto));  		clientSession->onSessionReady.connect(boost::bind(&IncomingJingleFileTransfer::proxySessionReady, this, candidate.jid, _1));  		clientSession->start(); diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.h b/Swiften/FileTransfer/IncomingJingleFileTransfer.h index 0731e04..1243d11 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.h +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.h @@ -35,6 +35,7 @@ namespace Swift {  	class SOCKS5BytestreamRegistry;  	class SOCKS5BytestreamProxy;  	class IncrementalBytestreamHashCalculator; +	class CryptoProvider;  	class SWIFTEN_API IncomingJingleFileTransfer : public IncomingFileTransfer {  		public: @@ -57,7 +58,8 @@ namespace Swift {  					IQRouter* router,  					SOCKS5BytestreamRegistry* bytestreamRegistry,  					SOCKS5BytestreamProxy* bytestreamProxy, -					TimerFactory*); +					TimerFactory*, +					CryptoProvider*);  			~IncomingJingleFileTransfer();  			virtual void accept(WriteBytestream::ref); @@ -103,6 +105,7 @@ namespace Swift {  			JingleSession::ref session;  			IQRouter* router;  			JingleContentPayload::ref initialContent; +			CryptoProvider* crypto;  			State state;  			JingleFileTransferDescription::ref description;  			WriteBytestream::ref stream; diff --git a/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.cpp b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.cpp index 6b53a1b..e669a51 100644 --- a/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.cpp +++ b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.cpp @@ -4,17 +4,23 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +  #include <Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h>  #include <Swiften/StringCodecs/Hexify.h> -#include <Swiften/StringCodecs/MD5.h> -#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/Crypto/CryptoProvider.h>  namespace Swift { -IncrementalBytestreamHashCalculator::IncrementalBytestreamHashCalculator(bool doMD5, bool doSHA1) { -	md5Hasher = doMD5 ? new MD5() : NULL; -	sha1Hasher = doSHA1 ? new SHA1() : NULL; +IncrementalBytestreamHashCalculator::IncrementalBytestreamHashCalculator(bool doMD5, bool doSHA1, CryptoProvider* crypto) { +	md5Hasher = doMD5 ? crypto->createMD5() : NULL; +	sha1Hasher = doSHA1 ? crypto->createSHA1() : NULL;  }  IncrementalBytestreamHashCalculator::~IncrementalBytestreamHashCalculator() { diff --git a/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h index 64f4b5f..f9f43b9 100644 --- a/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h +++ b/Swiften/FileTransfer/IncrementalBytestreamHashCalculator.h @@ -4,30 +4,35 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #pragma once  #include <Swiften/Base/ByteArray.h>  #include <Swiften/Base/SafeByteArray.h>  namespace Swift { +	class Hash; +	class CryptoProvider; -class MD5; -class SHA1; - -class IncrementalBytestreamHashCalculator { -public: -	IncrementalBytestreamHashCalculator(bool doMD5, bool doSHA1); -	~IncrementalBytestreamHashCalculator(); +	class IncrementalBytestreamHashCalculator { +	public: +		IncrementalBytestreamHashCalculator(bool doMD5, bool doSHA1, CryptoProvider* crypto); +		~IncrementalBytestreamHashCalculator(); -	void feedData(const ByteArray& data); -	//void feedData(const SafeByteArray& data); +		void feedData(const ByteArray& data); +		//void feedData(const SafeByteArray& data); -	std::string getSHA1String(); -	std::string getMD5String(); +		std::string getSHA1String(); +		std::string getMD5String(); -private: -	MD5* md5Hasher; -	SHA1* sha1Hasher; -}; +	private: +		Hash* md5Hasher; +		Hash* sha1Hasher; +	};  } diff --git a/Swiften/FileTransfer/OutgoingFileTransferManager.cpp b/Swiften/FileTransfer/OutgoingFileTransferManager.cpp index 6f23bb7..99ca175 100644 --- a/Swiften/FileTransfer/OutgoingFileTransferManager.cpp +++ b/Swiften/FileTransfer/OutgoingFileTransferManager.cpp @@ -4,6 +4,12 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #include "OutgoingFileTransferManager.h"  #include <boost/smart_ptr/make_shared.hpp> @@ -17,7 +23,7 @@  namespace Swift { -OutgoingFileTransferManager::OutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy) { +OutgoingFileTransferManager::OutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, CryptoProvider* crypto) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), crypto(crypto) {  	idGenerator = new IDGenerator();  } @@ -34,7 +40,7 @@ boost::shared_ptr<OutgoingFileTransfer> OutgoingFileTransferManager::createOutgo  	//jsManager->getSession(receipient, idGenerator->generateID());  	assert(jingleSession);  	jsManager->registerOutgoingSession(from, jingleSession); -	boost::shared_ptr<OutgoingJingleFileTransfer> jingleFT =  boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(jingleSession, remoteFactory, localFactory, iqRouter, idGenerator, from, receipient, readBytestream, fileInfo, bytestreamRegistry, bytestreamProxy)); +	boost::shared_ptr<OutgoingJingleFileTransfer> jingleFT =  boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(jingleSession, remoteFactory, localFactory, iqRouter, idGenerator, from, receipient, readBytestream, fileInfo, bytestreamRegistry, bytestreamProxy, crypto));  	// otherwise try SI diff --git a/Swiften/FileTransfer/OutgoingFileTransferManager.h b/Swiften/FileTransfer/OutgoingFileTransferManager.h index c686001..409c5ed 100644 --- a/Swiften/FileTransfer/OutgoingFileTransferManager.h +++ b/Swiften/FileTransfer/OutgoingFileTransferManager.h @@ -4,6 +4,12 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #pragma once  #include <boost/shared_ptr.hpp> @@ -24,10 +30,11 @@ class ReadBytestream;  class StreamInitiationFileInfo;  class SOCKS5BytestreamRegistry;  class SOCKS5BytestreamProxy; +class CryptoProvider;  class OutgoingFileTransferManager {  public: -	OutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy); +	OutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, CryptoProvider* crypto);  	~OutgoingFileTransferManager();  	boost::shared_ptr<OutgoingFileTransfer> createOutgoingFileTransfer(const JID& from, const JID& to, boost::shared_ptr<ReadBytestream>, const StreamInitiationFileInfo&); @@ -41,6 +48,7 @@ private:  	IDGenerator *idGenerator;  	SOCKS5BytestreamRegistry* bytestreamRegistry;  	SOCKS5BytestreamProxy* bytestreamProxy; +	CryptoProvider* crypto;  };  } diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp index 8229a2f..285dbe3 100644 --- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp @@ -28,7 +28,7 @@  #include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>  #include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h>  #include <Swiften/StringCodecs/Hexify.h> -#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/Crypto/CryptoProvider.h>  #include <Swiften/Base/Log.h> @@ -44,8 +44,9 @@ OutgoingJingleFileTransfer::OutgoingJingleFileTransfer(JingleSession::ref sessio  					boost::shared_ptr<ReadBytestream> readStream,  					const StreamInitiationFileInfo &fileInfo,  					SOCKS5BytestreamRegistry* bytestreamRegistry, -					SOCKS5BytestreamProxy* bytestreamProxy) : -	session(session), router(router), idGenerator(idGenerator), fromJID(fromJID), toJID(toJID), readStream(readStream), fileInfo(fileInfo), s5bRegistry(bytestreamRegistry), s5bProxy(bytestreamProxy), serverSession(NULL), contentID(JingleContentID(idGenerator->generateID(), JingleContentPayload::InitiatorCreator)), canceled(false) { +					SOCKS5BytestreamProxy* bytestreamProxy, +					CryptoProvider* crypto) : +	session(session), router(router), idGenerator(idGenerator), fromJID(fromJID), toJID(toJID), readStream(readStream), fileInfo(fileInfo), s5bRegistry(bytestreamRegistry), s5bProxy(bytestreamProxy), crypto(crypto), serverSession(NULL), contentID(JingleContentID(idGenerator->generateID(), JingleContentPayload::InitiatorCreator)), canceled(false) {  	session->onSessionAcceptReceived.connect(boost::bind(&OutgoingJingleFileTransfer::handleSessionAcceptReceived, this, _1, _2, _3));  	session->onSessionTerminateReceived.connect(boost::bind(&OutgoingJingleFileTransfer::handleSessionTerminateReceived, this, _1));  	session->onTransportInfoReceived.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransportInfoReceived, this, _1, _2)); @@ -60,7 +61,7 @@ OutgoingJingleFileTransfer::OutgoingJingleFileTransfer(JingleSession::ref sessio  	remoteCandidateSelector = remoteFactory->createCandidateSelector();  	remoteCandidateSelector->onRemoteTransportCandidateSelectFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleRemoteTransportCandidateSelectFinished, this, _1));  	// calculate both, MD5 and SHA-1 since we don't know which one the other side supports -	hashCalculator = new IncrementalBytestreamHashCalculator(true, true); +	hashCalculator = new IncrementalBytestreamHashCalculator(true, true, crypto);  	this->readStream->onRead.connect(boost::bind(&IncrementalBytestreamHashCalculator::feedData, hashCalculator, _1));  } @@ -92,7 +93,7 @@ void OutgoingJingleFileTransfer::cancel() {  	if (ibbSession) {  		ibbSession->stop();  	} -	SOCKS5BytestreamServerSession *serverSession = s5bRegistry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID)); +	SOCKS5BytestreamServerSession *serverSession = s5bRegistry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID, crypto));  	if (serverSession) {  		serverSession->stop();  	} @@ -200,14 +201,14 @@ void OutgoingJingleFileTransfer::startTransferViaTheirCandidateChoice(JingleS5BT  	SWIFT_LOG(debug) << "Transferring data using their candidate." << std::endl;  	if (candidate.type == JingleS5BTransportPayload::Candidate::ProxyType) {  		// connect to proxy -		clientSession = s5bProxy->createSOCKS5BytestreamClientSession(candidate.hostPort, SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID)); +		clientSession = s5bProxy->createSOCKS5BytestreamClientSession(candidate.hostPort, SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID, crypto));  		clientSession->onSessionReady.connect(boost::bind(&OutgoingJingleFileTransfer::proxySessionReady, this, candidate.jid, _1));  		clientSession->start();  		// on reply send activate  	} else { -		serverSession = s5bRegistry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID)); +		serverSession = s5bRegistry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID, crypto));  		serverSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1));  		serverSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1));  		serverSession->startTransfer(); @@ -356,7 +357,7 @@ void OutgoingJingleFileTransfer::handleLocalTransportCandidatesGenerated(JingleT  		fillCandidateMap(ourCandidates, emptyCandidates);  		transport = emptyCandidates; -		s5bRegistry->addReadBytestream(SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID), readStream); +		s5bRegistry->addReadBytestream(SOCKS5BytestreamRegistry::getHostname(s5bSessionID, session->getInitiator(), toJID, crypto), readStream);  	}  	else {  		SWIFT_LOG(debug) << "Unknown tranport payload: " << typeid(*payload).name() << std::endl; diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.h b/Swiften/FileTransfer/OutgoingJingleFileTransfer.h index e18b5c3..ee2c20e 100644 --- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.h +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.h @@ -19,7 +19,6 @@  #include <Swiften/FileTransfer/SOCKS5BytestreamServerSession.h>  #include <Swiften/Jingle/JingleContentID.h>  #include <Swiften/Jingle/JingleSession.h> -#include <Swiften/StringCodecs/SHA1.h>  namespace Swift { @@ -34,6 +33,7 @@ class IDGenerator;  class IncrementalBytestreamHashCalculator;  class SOCKS5BytestreamRegistry;  class SOCKS5BytestreamProxy; +class CryptoProvider;  class SWIFTEN_API OutgoingJingleFileTransfer : public OutgoingFileTransfer {  public: @@ -47,7 +47,8 @@ public:  					boost::shared_ptr<ReadBytestream>,  					const StreamInitiationFileInfo&,  					SOCKS5BytestreamRegistry*, -					SOCKS5BytestreamProxy*); +					SOCKS5BytestreamProxy*, +					CryptoProvider*);  	virtual ~OutgoingJingleFileTransfer();  	void start(); @@ -105,6 +106,7 @@ private:  	SOCKS5BytestreamRegistry* s5bRegistry;  	SOCKS5BytestreamProxy* s5bProxy; +	CryptoProvider* crypto;  	SOCKS5BytestreamClientSession::ref clientSession;  	SOCKS5BytestreamServerSession* serverSession;  	JingleContentID contentID; diff --git a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp index 1b3399f..a0b6e7f 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp @@ -13,7 +13,6 @@  #include <Swiften/Base/SafeByteArray.h>  #include <Swiften/Base/Concat.h>  #include <Swiften/Base/Log.h> -#include <Swiften/StringCodecs/SHA1.h>  #include <Swiften/StringCodecs/Hexify.h>  #include <Swiften/FileTransfer/BytestreamException.h>  #include <Swiften/Network/TimerFactory.h> diff --git a/Swiften/FileTransfer/SOCKS5BytestreamRegistry.cpp b/Swiften/FileTransfer/SOCKS5BytestreamRegistry.cpp index ffc4298..8939579 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamRegistry.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamRegistry.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -11,8 +11,8 @@  #include <Swiften/Base/Algorithm.h>  #include <Swiften/Base/Log.h>  #include <Swiften/Base/foreach.h> -#include <Swiften/StringCodecs/SHA1.h>  #include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/Crypto/CryptoProvider.h>  namespace Swift { @@ -64,8 +64,8 @@ SOCKS5BytestreamServerSession* SOCKS5BytestreamRegistry::getConnectedSession(con  	}  } -std::string SOCKS5BytestreamRegistry::getHostname(const std::string& sessionID, const JID& requester, const JID& target) { -	return Hexify::hexify(SHA1::getHash(createSafeByteArray(sessionID + requester.toString() + target.toString()))); +std::string SOCKS5BytestreamRegistry::getHostname(const std::string& sessionID, const JID& requester, const JID& target, CryptoProvider* crypto) { +	return Hexify::hexify(crypto->getSHA1Hash(createSafeByteArray(sessionID + requester.toString() + target.toString())));  }  } diff --git a/Swiften/FileTransfer/SOCKS5BytestreamRegistry.h b/Swiften/FileTransfer/SOCKS5BytestreamRegistry.h index 6d89e27..107707f 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamRegistry.h +++ b/Swiften/FileTransfer/SOCKS5BytestreamRegistry.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -24,6 +24,8 @@  #include <Swiften/Network/HostAddressPort.h>  namespace Swift { +	class CryptoProvider; +  	class SWIFTEN_API SOCKS5BytestreamRegistry {  		public:  			SOCKS5BytestreamRegistry(); @@ -47,7 +49,7 @@ namespace Swift {  			SOCKS5BytestreamServerSession* getConnectedSession(const std::string& destination);  		public: -			static std::string getHostname(const std::string& sessionID, const JID& requester, const JID& target); +			static std::string getHostname(const std::string& sessionID, const JID& requester, const JID& target, CryptoProvider* crypto);  		private:  			friend class SOCKS5BytestreamServerSession; diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServer.cpp b/Swiften/FileTransfer/SOCKS5BytestreamServer.cpp index 90fed7a..00c72a7 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamServer.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamServer.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -10,13 +10,13 @@  #include <Swiften/Base/Log.h>  #include <Swiften/StringCodecs/Hexify.h> -#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/Crypto/CryptoProvider.h>  #include <Swiften/FileTransfer/SOCKS5BytestreamServerSession.h>  #include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>  namespace Swift { -SOCKS5BytestreamServer::SOCKS5BytestreamServer(boost::shared_ptr<ConnectionServer> connectionServer, SOCKS5BytestreamRegistry* registry) : connectionServer(connectionServer), registry(registry) { +SOCKS5BytestreamServer::SOCKS5BytestreamServer(boost::shared_ptr<ConnectionServer> connectionServer, SOCKS5BytestreamRegistry* registry, CryptoProvider* crypto) : connectionServer(connectionServer), registry(registry), crypto(crypto) {  }  void SOCKS5BytestreamServer::start() { @@ -36,7 +36,7 @@ void SOCKS5BytestreamServer::removeReadBytestream(const std::string& id, const J  }  std::string SOCKS5BytestreamServer::getSOCKSDestinationAddress(const std::string& id, const JID& from, const JID& to) { -	return Hexify::hexify(SHA1::getHash(createByteArray(id + from.toString() + to.toString()))); +	return Hexify::hexify(crypto->getSHA1Hash(createByteArray(id + from.toString() + to.toString())));  }  void SOCKS5BytestreamServer::handleNewConnection(boost::shared_ptr<Connection> connection) { diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServer.h b/Swiften/FileTransfer/SOCKS5BytestreamServer.h index 6bb598e..b19ae90 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamServer.h +++ b/Swiften/FileTransfer/SOCKS5BytestreamServer.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -17,10 +17,11 @@  namespace Swift {  	class SOCKS5BytestreamServerSession; +	class CryptoProvider;  	class SOCKS5BytestreamServer {  		public: -			SOCKS5BytestreamServer(boost::shared_ptr<ConnectionServer> connectionServer, SOCKS5BytestreamRegistry* registry); +			SOCKS5BytestreamServer(boost::shared_ptr<ConnectionServer> connectionServer, SOCKS5BytestreamRegistry* registry, CryptoProvider* crypto);  			HostAddressPort getAddressPort() const; @@ -36,13 +37,14 @@ namespace Swift {  		private:  			void handleNewConnection(boost::shared_ptr<Connection> connection); -			static std::string getSOCKSDestinationAddress(const std::string& id, const JID& from, const JID& to); +			std::string getSOCKSDestinationAddress(const std::string& id, const JID& from, const JID& to);  		private:  			friend class SOCKS5BytestreamServerSession;  			boost::shared_ptr<ConnectionServer> connectionServer;  			SOCKS5BytestreamRegistry* registry; +			CryptoProvider* crypto;  			std::vector<boost::shared_ptr<SOCKS5BytestreamServerSession> > sessions;  	};  } diff --git a/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp index 9d180a0..47798ab 100644 --- a/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp +++ b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp @@ -4,6 +4,12 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h> @@ -30,6 +36,8 @@  #include <Swiften/Network/DummyConnectionFactory.h>  #include <Swiften/Network/PlatformNATTraversalWorker.h>  #include <Swiften/Queries/IQRouter.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  #include <iostream> @@ -122,7 +130,7 @@ class IncomingJingleFileTransferTest : public CppUnit::TestFixture {  public:  		shared_ptr<IncomingJingleFileTransfer> createTestling() {  			JID ourJID("our@jid.org/full"); -			return make_shared<IncomingJingleFileTransfer>(ourJID, shared_ptr<JingleSession>(fakeJingleSession), jingleContentPayload, fakeRJTCSF.get(), fakeLJTCF.get(), iqRouter, bytestreamRegistry, bytestreamProxy, timerFactory); +			return boost::shared_ptr<IncomingJingleFileTransfer>(new IncomingJingleFileTransfer(ourJID, shared_ptr<JingleSession>(fakeJingleSession), jingleContentPayload, fakeRJTCSF.get(), fakeLJTCF.get(), iqRouter, bytestreamRegistry, bytestreamProxy, timerFactory, crypto.get()));  		}  		IQ::ref createIBBRequest(IBB::ref ibb, const JID& from, const std::string& id) { @@ -132,6 +140,7 @@ public:  		}  		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());  			eventLoop = new DummyEventLoop();  			fakeJingleSession = new FakeJingleSession("foo@bar.com/baz", "mysession");  			jingleContentPayload = make_shared<JingleContentPayload>(); @@ -280,6 +289,7 @@ private:  	DummyConnectionFactory* connectionFactory;  	SOCKS5BytestreamProxy* bytestreamProxy;  	DummyTimerFactory* timerFactory; +	boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(IncomingJingleFileTransferTest); diff --git a/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp index 73b496a..1dc7fba 100644 --- a/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp +++ b/Swiften/FileTransfer/UnitTest/OutgoingJingleFileTransferTest.cpp @@ -4,6 +4,12 @@   * See Documentation/Licenses/BSD-simplified.txt for more information.   */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ +  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h> @@ -36,6 +42,8 @@  #include <Swiften/Network/DummyConnection.h>  #include <Swiften/Network/ConnectionFactory.h>  #include <Swiften/Network/DummyConnectionFactory.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  #include <Swiften/Base/Log.h> @@ -147,7 +155,7 @@ public:  			fileInfo.setName("test.bin");  			fileInfo.setHash("asdjasdas");  			fileInfo.setSize(1024 * 1024); -			return boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(boost::shared_ptr<JingleSession>(fakeJingleSession), fakeRJTCSF.get(), fakeLJTCF.get(), iqRouter, idGen, JID(), to, stream, fileInfo, s5bRegistry, s5bProxy)); +			return boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(boost::shared_ptr<JingleSession>(fakeJingleSession), fakeRJTCSF.get(), fakeLJTCF.get(), iqRouter, idGen, JID(), to, stream, fileInfo, s5bRegistry, s5bProxy, crypto.get()));  		}  		IQ::ref createIBBRequest(IBB::ref ibb, const JID& from, const std::string& id) { @@ -157,6 +165,7 @@ public:  		}  		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());  			fakeJingleSession = new FakeJingleSession("foo@bar.com/baz", "mysession");  			jingleContentPayload = boost::make_shared<JingleContentPayload>();  			fakeRJTCSF = boost::make_shared<OFakeRemoteJingleTransportCandidateSelectorFactory>(); @@ -281,6 +290,7 @@ private:  	SOCKS5BytestreamProxy* s5bProxy;  	DummyTimerFactory* timerFactory;  	DummyConnectionFactory* connectionFactory; +	boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(OutgoingJingleFileTransferTest); diff --git a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp index 502cf2d..65ff290 100644 --- a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp +++ b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp @@ -30,6 +30,8 @@  #include <Swiften/Network/DummyConnection.h>  #include <Swiften/Network/DummyTimerFactory.h>  #include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -44,14 +46,12 @@ class SOCKS5BytestreamClientSessionTest : public CppUnit::TestFixture {  	CPPUNIT_TEST(testReadBytestream);  	CPPUNIT_TEST_SUITE_END(); -	const HostAddressPort destinationAddressPort; -	const std::string destination; -  public: -	SOCKS5BytestreamClientSessionTest() : destinationAddressPort(HostAddressPort(HostAddress("127.0.0.1"), 8888)), -		destination(SOCKS5BytestreamRegistry::getHostname("foo", JID("requester@example.com/test"), JID("target@example.com/test"))), eventLoop(NULL), timerFactory(NULL) { } +	SOCKS5BytestreamClientSessionTest() : destinationAddressPort(HostAddressPort(HostAddress("127.0.0.1"), 8888)) {}  	void setUp() { +		crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); +		destination = SOCKS5BytestreamRegistry::getHostname("foo", JID("requester@example.com/test"), JID("target@example.com/test"), crypto.get());  		randomGen.seed(static_cast<unsigned int>(time(NULL)));  		eventLoop = new DummyEventLoop();  		timerFactory = new DummyTimerFactory(); @@ -297,10 +297,13 @@ private:  	};  private: +	HostAddressPort destinationAddressPort; +	std::string destination;  	DummyEventLoop* eventLoop;  	DummyTimerFactory* timerFactory;  	boost::shared_ptr<MockeryConnection> connection;  	const std::vector<HostAddressPort> failingPorts; +	boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(SOCKS5BytestreamClientSessionTest); diff --git a/Swiften/Network/BoostNetworkFactories.cpp b/Swiften/Network/BoostNetworkFactories.cpp index 1265682..9f781e4 100644 --- a/Swiften/Network/BoostNetworkFactories.cpp +++ b/Swiften/Network/BoostNetworkFactories.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010-2012 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -17,6 +17,8 @@  #include <Swiften/Network/PlatformProxyProvider.h>  #include <Swiften/IDN/PlatformIDNConverter.h>  #include <Swiften/IDN/IDNConverter.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h> +#include <Swiften/Crypto/CryptoProvider.h>  namespace Swift { @@ -35,9 +37,11 @@ BoostNetworkFactories::BoostNetworkFactories(EventLoop* eventLoop) : eventLoop(e  	proxyProvider = new PlatformProxyProvider();  	idnConverter = PlatformIDNConverter::create();  	domainNameResolver = new PlatformDomainNameResolver(idnConverter, eventLoop); +	cryptoProvider = PlatformCryptoProvider::create();  }  BoostNetworkFactories::~BoostNetworkFactories() { +	delete cryptoProvider;  	delete domainNameResolver;  	delete idnConverter;  	delete proxyProvider; diff --git a/Swiften/Network/BoostNetworkFactories.h b/Swiften/Network/BoostNetworkFactories.h index 8bf3576..9c3bab1 100644 --- a/Swiften/Network/BoostNetworkFactories.h +++ b/Swiften/Network/BoostNetworkFactories.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010-2012 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -67,6 +67,10 @@ namespace Swift {  				return idnConverter;  			} +			virtual CryptoProvider* getCryptoProvider() const SWIFTEN_OVERRIDE { +				return cryptoProvider; +			} +  		private:  			BoostIOServiceThread ioServiceThread;  			TimerFactory* timerFactory; @@ -80,5 +84,6 @@ namespace Swift {  			ProxyProvider* proxyProvider;  			EventLoop* eventLoop;  			IDNConverter* idnConverter; +			CryptoProvider* cryptoProvider;  	};  } diff --git a/Swiften/Network/NetworkFactories.h b/Swiften/Network/NetworkFactories.h index 228d92d..dd8e216 100644 --- a/Swiften/Network/NetworkFactories.h +++ b/Swiften/Network/NetworkFactories.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010-2012 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -19,6 +19,7 @@ namespace Swift {  	class EventLoop;  	class IDNConverter;  	class NetworkEnvironment; +	class CryptoProvider;  	/**  	 * An interface collecting network factories. @@ -38,5 +39,6 @@ namespace Swift {  			virtual ProxyProvider* getProxyProvider() const = 0;  			virtual EventLoop* getEventLoop() const = 0;  			virtual IDNConverter* getIDNConverter() const = 0; +			virtual CryptoProvider* getCryptoProvider() const = 0;  	};  } diff --git a/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp b/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp index 249a538..74cdb85 100644 --- a/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp +++ b/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -8,18 +8,14 @@  #include <cassert> -#include <Swiften/StringCodecs/MD5.h>  #include <Swiften/StringCodecs/Hexify.h>  #include <Swiften/Base/Concat.h>  #include <Swiften/Base/Algorithm.h> +#include <Swiften/Crypto/CryptoProvider.h>  namespace Swift { -DIGESTMD5ClientAuthenticator::DIGESTMD5ClientAuthenticator(const std::string& host, const std::string& nonce) : ClientAuthenticator("DIGEST-MD5"), step(Initial), host(host), cnonce(nonce) { -} - -bool DIGESTMD5ClientAuthenticator::canBeUsed() { -	return MD5::isAllowedForCrypto(); +DIGESTMD5ClientAuthenticator::DIGESTMD5ClientAuthenticator(const std::string& host, const std::string& nonce, CryptoProvider* crypto) : ClientAuthenticator("DIGEST-MD5"), step(Initial), host(host), cnonce(nonce), crypto(crypto) {  }  boost::optional<SafeByteArray> DIGESTMD5ClientAuthenticator::getResponse() const { @@ -37,7 +33,7 @@ boost::optional<SafeByteArray> DIGESTMD5ClientAuthenticator::getResponse() const  		// Compute the response value  		ByteArray A1 = concat( -				MD5::getHash( +				crypto->getMD5Hash(  					concat(createSafeByteArray(getAuthenticationID().c_str()), createSafeByteArray(":"), createSafeByteArray(realm.c_str()), createSafeByteArray(":"), getPassword())),  				createByteArray(":"), createByteArray(*challenge.getValue("nonce")), createByteArray(":"), createByteArray(cnonce));  		if (!getAuthorizationID().empty()) { @@ -45,10 +41,10 @@ boost::optional<SafeByteArray> DIGESTMD5ClientAuthenticator::getResponse() const  		}  		ByteArray A2 = createByteArray("AUTHENTICATE:" + digestURI); -		std::string responseValue = Hexify::hexify(MD5::getHash(createByteArray( -			Hexify::hexify(MD5::getHash(A1)) + ":" +		std::string responseValue = Hexify::hexify(crypto->getMD5Hash(createByteArray( +			Hexify::hexify(crypto->getMD5Hash(A1)) + ":"  			+ *challenge.getValue("nonce") + ":" + nc + ":" + cnonce + ":" + qop + ":" -			+ Hexify::hexify(MD5::getHash(A2))))); +			+ Hexify::hexify(crypto->getMD5Hash(A2)))));  		DIGESTMD5Properties response; diff --git a/Swiften/SASL/DIGESTMD5ClientAuthenticator.h b/Swiften/SASL/DIGESTMD5ClientAuthenticator.h index 813ded2..d141401 100644 --- a/Swiften/SASL/DIGESTMD5ClientAuthenticator.h +++ b/Swiften/SASL/DIGESTMD5ClientAuthenticator.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -16,13 +16,14 @@  #include <Swiften/Base/SafeByteArray.h>  namespace Swift { +	class CryptoProvider; +  	class SWIFTEN_API DIGESTMD5ClientAuthenticator : public ClientAuthenticator {  		public: -			DIGESTMD5ClientAuthenticator(const std::string& host, const std::string& nonce); +			DIGESTMD5ClientAuthenticator(const std::string& host, const std::string& nonce, CryptoProvider*);  			virtual boost::optional<SafeByteArray> getResponse() const;  			virtual bool setChallenge(const boost::optional<std::vector<unsigned char> >&); -			static bool canBeUsed();  		private:  			enum Step { @@ -32,6 +33,7 @@ namespace Swift {  			} step;  			std::string host;  			std::string cnonce; +			CryptoProvider* crypto;  			DIGESTMD5Properties challenge;  	};  } diff --git a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp index 38e3289..44fef76 100644 --- a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp +++ b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp @@ -10,9 +10,8 @@  #include <map>  #include <boost/lexical_cast.hpp> -#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/Crypto/CryptoProvider.h>  #include <Swiften/StringCodecs/Base64.h> -#include <Swiften/StringCodecs/HMAC_SHA1.h>  #include <Swiften/StringCodecs/PBKDF2.h>  #include <Swiften/IDN/IDNConverter.h>  #include <Swiften/Base/Concat.h> @@ -36,7 +35,7 @@ static std::string escape(const std::string& s) {  } -SCRAMSHA1ClientAuthenticator::SCRAMSHA1ClientAuthenticator(const std::string& nonce, bool useChannelBinding, IDNConverter* idnConverter) : ClientAuthenticator(useChannelBinding ? "SCRAM-SHA-1-PLUS" : "SCRAM-SHA-1"), step(Initial), clientnonce(nonce), useChannelBinding(useChannelBinding), idnConverter(idnConverter) { +SCRAMSHA1ClientAuthenticator::SCRAMSHA1ClientAuthenticator(const std::string& nonce, bool useChannelBinding, IDNConverter* idnConverter, CryptoProvider* crypto) : ClientAuthenticator(useChannelBinding ? "SCRAM-SHA-1-PLUS" : "SCRAM-SHA-1"), step(Initial), clientnonce(nonce), useChannelBinding(useChannelBinding), idnConverter(idnConverter), crypto(crypto) {  }  boost::optional<SafeByteArray> SCRAMSHA1ClientAuthenticator::getResponse() const { @@ -44,9 +43,9 @@ boost::optional<SafeByteArray> SCRAMSHA1ClientAuthenticator::getResponse() const  		return createSafeByteArray(concat(getGS2Header(), getInitialBareClientMessage()));  	}  	else if (step == Proof) { -		ByteArray clientKey = HMAC_SHA1()(saltedPassword, createByteArray("Client Key")); -		ByteArray storedKey = SHA1::getHash(clientKey); -		ByteArray clientSignature = HMAC_SHA1()(createSafeByteArray(storedKey), authMessage); +		ByteArray clientKey = crypto->getHMACSHA1(saltedPassword, createByteArray("Client Key")); +		ByteArray storedKey = crypto->getSHA1Hash(clientKey); +		ByteArray clientSignature = crypto->getHMACSHA1(createSafeByteArray(storedKey), authMessage);  		ByteArray clientProof = clientKey;  		for (unsigned int i = 0; i < clientProof.size(); ++i) {  			clientProof[i] ^= clientSignature[i]; @@ -96,13 +95,13 @@ bool SCRAMSHA1ClientAuthenticator::setChallenge(const boost::optional<ByteArray>  		// Compute all the values needed for the server signature  		try { -			saltedPassword = PBKDF2::encode<HMAC_SHA1>(idnConverter->getStringPrepared(getPassword(), IDNConverter::SASLPrep), salt, iterations); +			saltedPassword = PBKDF2::encode(idnConverter->getStringPrepared(getPassword(), IDNConverter::SASLPrep), salt, iterations, crypto);  		}  		catch (const std::exception&) {  		}  		authMessage = concat(getInitialBareClientMessage(), createByteArray(","), initialServerMessage, createByteArray(","), getFinalMessageWithoutProof()); -		ByteArray serverKey = HMAC_SHA1()(saltedPassword, createByteArray("Server Key")); -		serverSignature = HMAC_SHA1()(serverKey, authMessage); +		ByteArray serverKey = crypto->getHMACSHA1(saltedPassword, createByteArray("Server Key")); +		serverSignature = crypto->getHMACSHA1(serverKey, authMessage);  		step = Proof;  		return true; diff --git a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h index da52bbc..b713f9f 100644 --- a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h +++ b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -16,10 +16,11 @@  namespace Swift {  	class IDNConverter; +	class CryptoProvider;  	class SWIFTEN_API SCRAMSHA1ClientAuthenticator : public ClientAuthenticator {  		public: -			SCRAMSHA1ClientAuthenticator(const std::string& nonce, bool useChannelBinding, IDNConverter*); +			SCRAMSHA1ClientAuthenticator(const std::string& nonce, bool useChannelBinding, IDNConverter*, CryptoProvider*);  			void setTLSChannelBindingData(const ByteArray& channelBindingData); @@ -47,6 +48,7 @@ namespace Swift {  			ByteArray serverSignature;  			bool useChannelBinding;  			IDNConverter* idnConverter; +			CryptoProvider* crypto;  			boost::optional<ByteArray> tlsChannelBindingData;  	};  } diff --git a/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp b/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp index 38bab15..94bcd0a 100644 --- a/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp +++ b/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -12,6 +12,9 @@  #include <Swiften/SASL/DIGESTMD5ClientAuthenticator.h>  #include <Swiften/Base/ByteArray.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h> +  using namespace Swift;  class DIGESTMD5ClientAuthenticatorTest : public CppUnit::TestFixture { @@ -23,14 +26,18 @@ class DIGESTMD5ClientAuthenticatorTest : public CppUnit::TestFixture {  		CPPUNIT_TEST_SUITE_END();  	public: +		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); +		} +  		void testGetInitialResponse() { -			DIGESTMD5ClientAuthenticator testling("xmpp.example.com", "abcdefgh"); +			DIGESTMD5ClientAuthenticator testling("xmpp.example.com", "abcdefgh", crypto.get());  			CPPUNIT_ASSERT(!testling.getResponse());  		}  		void testGetResponse() { -			DIGESTMD5ClientAuthenticator testling("xmpp.example.com", "abcdefgh"); +			DIGESTMD5ClientAuthenticator testling("xmpp.example.com", "abcdefgh", crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			testling.setChallenge(createByteArray( @@ -44,7 +51,7 @@ class DIGESTMD5ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testGetResponse_WithAuthorizationID() { -			DIGESTMD5ClientAuthenticator testling("xmpp.example.com", "abcdefgh"); +			DIGESTMD5ClientAuthenticator testling("xmpp.example.com", "abcdefgh", crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "myauthzid");  			testling.setChallenge(createByteArray( @@ -56,6 +63,9 @@ class DIGESTMD5ClientAuthenticatorTest : public CppUnit::TestFixture {  			CPPUNIT_ASSERT_EQUAL(createSafeByteArray("authzid=\"myauthzid\",charset=utf-8,cnonce=\"abcdefgh\",digest-uri=\"xmpp/xmpp.example.com\",nc=00000001,nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\",qop=auth,realm=\"example.com\",response=4293834432b6e7889a2dee7e8fe7dd06,username=\"user\""), response);  		} +	 +	private: +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(DIGESTMD5ClientAuthenticatorTest); diff --git a/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp b/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp index 6266f3e..3341ad8 100644 --- a/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp +++ b/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp @@ -13,6 +13,8 @@  #include <Swiften/Base/ByteArray.h>  #include <Swiften/IDN/IDNConverter.h>  #include <Swiften/IDN/PlatformIDNConverter.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -42,10 +44,11 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  	public:  		void setUp() {  			idnConverter = boost::shared_ptr<IDNConverter>(PlatformIDNConverter::create()); +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());  		}  		void testGetInitialResponse() { -			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			SafeByteArray response = *testling.getResponse(); @@ -54,7 +57,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testGetInitialResponse_UsernameHasSpecialChars() { -			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", false, idnConverter.get(), crypto.get());  			testling.setCredentials(",us=,er=", createSafeByteArray("pass"), "");  			SafeByteArray response = *testling.getResponse(); @@ -63,7 +66,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testGetInitialResponse_WithAuthorizationID() { -			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "auth");  			SafeByteArray response = *testling.getResponse(); @@ -72,7 +75,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testGetInitialResponse_WithAuthorizationIDWithSpecialChars() { -			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "a=u,th");  			SafeByteArray response = *testling.getResponse(); @@ -81,7 +84,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testGetInitialResponse_WithoutChannelBindingWithTLSChannelBindingData() { -			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", false, idnConverter.get(), crypto.get());  			testling.setTLSChannelBindingData(createByteArray("xyza"));  			testling.setCredentials("user", createSafeByteArray("pass"), ""); @@ -91,7 +94,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testGetInitialResponse_WithChannelBindingWithTLSChannelBindingData() { -			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", true, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH", true, idnConverter.get(), crypto.get());  			testling.setTLSChannelBindingData(createByteArray("xyza"));  			testling.setCredentials("user", createSafeByteArray("pass"), ""); @@ -101,7 +104,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testGetFinalResponse() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); @@ -111,7 +114,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testGetFinalResponse_WithoutChannelBindingWithTLSChannelBindingData() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			testling.setTLSChannelBindingData(createByteArray("xyza"));  			testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); @@ -122,7 +125,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testGetFinalResponse_WithChannelBindingWithTLSChannelBindingData() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", true, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", true, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			testling.setTLSChannelBindingData(createByteArray("xyza"));  			testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); @@ -133,7 +136,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testSetFinalChallenge() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); @@ -143,7 +146,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testSetChallenge() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			bool result = testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); @@ -152,7 +155,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testSetChallenge_InvalidClientNonce() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			bool result = testling.setChallenge(createByteArray("r=abcdefgiABCDEFGH,s=MTIzNDU2NzgK,i=4096")); @@ -161,7 +164,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testSetChallenge_OnlyClientNonce() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			bool result = testling.setChallenge(createByteArray("r=abcdefgh,s=MTIzNDU2NzgK,i=4096")); @@ -170,7 +173,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testSetChallenge_InvalidIterations() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			bool result = testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=bla")); @@ -179,7 +182,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testSetChallenge_MissingIterations() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			bool result = testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK")); @@ -188,7 +191,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testSetChallenge_ZeroIterations() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			bool result = testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=0")); @@ -197,7 +200,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testSetChallenge_NegativeIterations() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			bool result = testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=-1")); @@ -206,7 +209,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testSetFinalChallenge_InvalidChallenge() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096"));  			bool result = testling.setChallenge(createByteArray("v=e26kI69ICb6zosapLLxrER/631A=")); @@ -215,7 +218,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		void testGetResponseAfterFinalChallenge() { -			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get()); +			SCRAMSHA1ClientAuthenticator testling("abcdefgh", false, idnConverter.get(), crypto.get());  			testling.setCredentials("user", createSafeByteArray("pass"), "");  			testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096"));  			testling.setChallenge(createByteArray("v=Dd+Q20knZs9jeeK0pi1Mx1Se+yo=")); @@ -224,6 +227,7 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {  		}  		boost::shared_ptr<IDNConverter> idnConverter; +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(SCRAMSHA1ClientAuthenticatorTest); diff --git a/Swiften/SConscript b/Swiften/SConscript index b9fad17..1cb3543 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -221,8 +221,6 @@ if env["SCONS_STAGE"] == "build" :  			"Session/BasicSessionStream.cpp",  			"Session/BOSHSessionStream.cpp",  			"StringCodecs/Base64.cpp", -			"StringCodecs/SHA256.cpp", -			"StringCodecs/MD5.cpp",  			"StringCodecs/Hexify.cpp",  			"Whiteboard/WhiteboardResponder.cpp",  			"Whiteboard/WhiteboardSession.cpp", @@ -241,6 +239,7 @@ if env["SCONS_STAGE"] == "build" :  			"IDN",  			"SASL",  			"TLS", +			"Crypto",  			"EventLoop",  			"Parser",  			"JID", @@ -267,11 +266,6 @@ if env["SCONS_STAGE"] == "build" :  		])  	myenv = swiften_env.Clone() -	if myenv["PLATFORM"] == "win32": -		sources.append("StringCodecs/SHA1_Windows.cpp") -	else: -		sources.append("StringCodecs/SHA1.cpp") -  	if myenv["PLATFORM"] != "darwin" and myenv["PLATFORM"] != "win32" and myenv.get("HAVE_GCONF", 0) :  		env.MergeFlags(env["GCONF_FLAGS"]) @@ -441,11 +435,7 @@ if env["SCONS_STAGE"] == "build" :  			File("StreamStack/UnitTest/StreamStackTest.cpp"),  			File("StreamStack/UnitTest/XMPPLayerTest.cpp"),  			File("StringCodecs/UnitTest/Base64Test.cpp"), -			File("StringCodecs/UnitTest/SHA1Test.cpp"), -			File("StringCodecs/UnitTest/SHA256Test.cpp"), -			File("StringCodecs/UnitTest/MD5Test.cpp"),  			File("StringCodecs/UnitTest/HexifyTest.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 deleted file mode 100644 index 8b02d88..0000000 --- a/Swiften/StringCodecs/HMAC.h +++ /dev/null @@ -1,67 +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/SafeByteArray.h> -#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/HMAC_SHA1.h b/Swiften/StringCodecs/HMAC_SHA1.h deleted file mode 100644 index 8f403c6..0000000 --- a/Swiften/StringCodecs/HMAC_SHA1.h +++ /dev/null @@ -1,14 +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/StringCodecs/HMAC.h> -#include <Swiften/StringCodecs/SHA1.h> - -namespace Swift { -	typedef HMAC<SHA1, 64> HMAC_SHA1; -} diff --git a/Swiften/StringCodecs/HMAC_SHA256.h b/Swiften/StringCodecs/HMAC_SHA256.h deleted file mode 100644 index 2d856cb..0000000 --- a/Swiften/StringCodecs/HMAC_SHA256.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * 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/MD5.cpp b/Swiften/StringCodecs/MD5.cpp deleted file mode 100644 index ffed37b..0000000 --- a/Swiften/StringCodecs/MD5.cpp +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright (c) 2010-2012 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -/* - * This implementation is shamelessly copied from L. Peter Deutsch's - * implementation, and altered to use our own defines and datastructures. - * Original license below. - *//* -	Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved. - -	This software is provided 'as-is', without any express or implied -	warranty.  In no event will the authors be held liable for any damages -	arising from the use of this software. - -	Permission is granted to anyone to use this software for any purpose, -	including commercial applications, and to alter it and redistribute it -	freely, subject to the following restrictions: - -	1. The origin of this software must not be misrepresented; you must not -		 claim that you wrote the original software. If you use this software -		 in a product, an acknowledgment in the product documentation would be -		 appreciated but is not required. -	2. Altered source versions must be plainly marked as such, and must not be -		 misrepresented as being the original software. -	3. This notice may not be removed or altered from any source distribution. - -	L. Peter Deutsch -	ghost@aladdin.com - */ - -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma clang diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wcast-align" -#pragma clang diagnostic ignored "-Wmissing-prototypes" - -#include <Swiften/StringCodecs/MD5.h> - -#include <cassert> -#include <string.h> - -#include <Swiften/Base/ByteArray.h> -#include <Swiften/Base/Platform.h> - -#ifdef SWIFTEN_PLATFORM_WIN32 -#include <Swiften/Base/WindowsRegistry.h> -#endif - -namespace Swift { - -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ - -/* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s { -		md5_word_t count[2];				/* message length in bits, lsw first */ -		md5_word_t abcd[4];					/* digest buffer */ -		md5_byte_t buf[64];					/* accumulate block */ -} md5_state_t; - -#define T_MASK ((md5_word_t)~0) -#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) -#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -#define T3		0x242070db -#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) -#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -#define T6		0x4787c62a -#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) -#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -#define T9		0x698098d8 -#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) -#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) -#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -#define T13		 0x6b901122 -#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) -#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -#define T16		 0x49b40821 -#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) -#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -#define T19		 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) -#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -#define T22		 0x02441453 -#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) -#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -#define T25		 0x21e1cde6 -#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) -#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -#define T28		 0x455a14ed -#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) -#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -#define T31		 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) -#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) -#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -#define T35		 0x6d9d6122 -#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) -#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -#define T38		 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) -#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -#define T41		 0x289b7ec6 -#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) -#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -#define T44		 0x04881d05 -#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) -#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -#define T47		 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) -#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -#define T50		 0x432aff97 -#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) -#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -#define T53		 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) -#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) -#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -#define T57		 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) -#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -#define T60		 0x4e0811a1 -#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) -#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -#define T63		 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) - - -static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) { -		md5_word_t -		a = pms->abcd[0], b = pms->abcd[1], -		c = pms->abcd[2], d = pms->abcd[3]; -		md5_word_t t; -#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 - -		{ -#ifdef SWIFTEN_LITTLE_ENDIAN -				{ -						/* -						 * On little-endian machines, we can process properly aligned -						 * data without copying it. -						 */ -						if (!((data - (const md5_byte_t *)0) & 3)) { -								/* data are properly aligned */ -								X = (const md5_word_t *)data; -						} else { -								/* not aligned */ -								memcpy(xbuf, data, 64); -								X = xbuf; -						} -				} -#else -				{ -						/* -						 * On big-endian machines, we must arrange the bytes in the -						 * right order. -						 */ -						const md5_byte_t *xp = data; -						int i; - -						for (i = 0; i < 16; ++i, xp += 4) -								X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); -				} -#endif -		} - -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - -		/* Round 1. */ -		/* Let [abcd k s i] denote the operation -			 a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti)\ -	t = a + F(b,c,d) + X[k] + Ti;\ -	a = ROTATE_LEFT(t, s) + b -		/* Do the following 16 operations. */ -		SET(a, b, c, d,  0,  7,  T1); -		SET(d, a, b, c,  1, 12,  T2); -		SET(c, d, a, b,  2, 17,  T3); -		SET(b, c, d, a,  3, 22,  T4); -		SET(a, b, c, d,  4,  7,  T5); -		SET(d, a, b, c,  5, 12,  T6); -		SET(c, d, a, b,  6, 17,  T7); -		SET(b, c, d, a,  7, 22,  T8); -		SET(a, b, c, d,  8,  7,  T9); -		SET(d, a, b, c,  9, 12, T10); -		SET(c, d, a, b, 10, 17, T11); -		SET(b, c, d, a, 11, 22, T12); -		SET(a, b, c, d, 12,  7, T13); -		SET(d, a, b, c, 13, 12, T14); -		SET(c, d, a, b, 14, 17, T15); -		SET(b, c, d, a, 15, 22, T16); -#undef SET - -		 /* Round 2. */ -		 /* Let [abcd k s i] denote the operation -					a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ -	t = a + G(b,c,d) + X[k] + Ti;\ -	a = ROTATE_LEFT(t, s) + b -		 /* Do the following 16 operations. */ -		SET(a, b, c, d,  1,  5, T17); -		SET(d, a, b, c,  6,  9, T18); -		SET(c, d, a, b, 11, 14, T19); -		SET(b, c, d, a,  0, 20, T20); -		SET(a, b, c, d,  5,  5, T21); -		SET(d, a, b, c, 10,  9, T22); -		SET(c, d, a, b, 15, 14, T23); -		SET(b, c, d, a,  4, 20, T24); -		SET(a, b, c, d,  9,  5, T25); -		SET(d, a, b, c, 14,  9, T26); -		SET(c, d, a, b,  3, 14, T27); -		SET(b, c, d, a,  8, 20, T28); -		SET(a, b, c, d, 13,  5, T29); -		SET(d, a, b, c,  2,  9, T30); -		SET(c, d, a, b,  7, 14, T31); -		SET(b, c, d, a, 12, 20, T32); -#undef SET - -		 /* Round 3. */ -		 /* Let [abcd k s t] denote the operation -					a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti)\ -	t = a + H(b,c,d) + X[k] + Ti;\ -	a = ROTATE_LEFT(t, s) + b -		 /* Do the following 16 operations. */ -		SET(a, b, c, d,  5,  4, T33); -		SET(d, a, b, c,  8, 11, T34); -		SET(c, d, a, b, 11, 16, T35); -		SET(b, c, d, a, 14, 23, T36); -		SET(a, b, c, d,  1,  4, T37); -		SET(d, a, b, c,  4, 11, T38); -		SET(c, d, a, b,  7, 16, T39); -		SET(b, c, d, a, 10, 23, T40); -		SET(a, b, c, d, 13,  4, T41); -		SET(d, a, b, c,  0, 11, T42); -		SET(c, d, a, b,  3, 16, T43); -		SET(b, c, d, a,  6, 23, T44); -		SET(a, b, c, d,  9,  4, T45); -		SET(d, a, b, c, 12, 11, T46); -		SET(c, d, a, b, 15, 16, T47); -		SET(b, c, d, a,  2, 23, T48); -#undef SET - -		 /* Round 4. */ -		 /* Let [abcd k s t] denote the operation -					a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ -	t = a + I(b,c,d) + X[k] + Ti;\ -	a = ROTATE_LEFT(t, s) + b -		 /* Do the following 16 operations. */ -		SET(a, b, c, d,  0,  6, T49); -		SET(d, a, b, c,  7, 10, T50); -		SET(c, d, a, b, 14, 15, T51); -		SET(b, c, d, a,  5, 21, T52); -		SET(a, b, c, d, 12,  6, T53); -		SET(d, a, b, c,  3, 10, T54); -		SET(c, d, a, b, 10, 15, T55); -		SET(b, c, d, a,  1, 21, T56); -		SET(a, b, c, d,  8,  6, T57); -		SET(d, a, b, c, 15, 10, T58); -		SET(c, d, a, b,  6, 15, T59); -		SET(b, c, d, a, 13, 21, T60); -		SET(a, b, c, d,  4,  6, T61); -		SET(d, a, b, c, 11, 10, T62); -		SET(c, d, a, b,  2, 15, T63); -		SET(b, c, d, a,  9, 21, T64); -#undef SET - -		 /* Then perform the following additions. (That is increment each -				of the four registers by the value it had before this block -				was started.) */ -		pms->abcd[0] += a; -		pms->abcd[1] += b; -		pms->abcd[2] += c; -		pms->abcd[3] += d; -} - -void -md5_init(md5_state_t *pms) -{ -		pms->count[0] = pms->count[1] = 0; -		pms->abcd[0] = 0x67452301; -		pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; -		pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; -		pms->abcd[3] = 0x10325476; -} - -void -md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) -{ -		const md5_byte_t *p = data; -		int left = nbytes; -		int offset = (pms->count[0] >> 3) & 63; -		md5_word_t nbits = (md5_word_t)(nbytes << 3); - -		if (nbytes <= 0) -				return; - -		/* Update the message length. */ -		pms->count[1] += nbytes >> 29; -		pms->count[0] += nbits; -		if (pms->count[0] < nbits) -				pms->count[1]++; - -		/* Process an initial partial block. */ -		if (offset) { -				int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - -				memcpy(pms->buf + offset, p, copy); -				if (offset + copy < 64) -						return; -				p += copy; -				left -= copy; -				md5_process(pms, pms->buf); -		} - -		/* Process full blocks. */ -		for (; left >= 64; p += 64, left -= 64) -				md5_process(pms, p); - -		/* Process a final partial block. */ -		if (left) -				memcpy(pms->buf, p, left); -} - -void -md5_finish(md5_state_t *pms, md5_byte_t digest[16]) -{ -		static const md5_byte_t pad[64] = { -				0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -		}; -		md5_byte_t data[8]; -		int i; - -		/* Save the length before padding. */ -		for (i = 0; i < 8; ++i) -				data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); -		/* Pad to 56 bytes mod 64. */ -		md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); -		/* Append the length. */ -		md5_append(pms, data, 8); -		for (i = 0; i < 16; ++i) -				digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -} - -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::MD5() { -	state = new md5_state_t; -	md5_init(state); -} - -MD5::~MD5() { -	delete state; -} - -MD5& MD5::update(const std::vector<unsigned char>& input) { -	md5_append(state, reinterpret_cast<const md5_byte_t*>(vecptr(input)), input.size()); -	return *this; -} - -std::vector<unsigned char> MD5::getHash() { -	ByteArray digest; -	digest.resize(16); -	md5_finish(state, reinterpret_cast<md5_byte_t*>(vecptr(digest))); -	return digest; -} - -ByteArray MD5::getHash(const ByteArray& data) { -	return getMD5Hash(data); -} - -ByteArray MD5::getHash(const SafeByteArray& data) { -	return getMD5Hash(data); -} - -bool MD5::isAllowedForCrypto() { -#ifdef SWIFTEN_PLATFORM_WIN32 -	return !WindowsRegistry::isFIPSEnabled(); -#else -	return true; -#endif -} - -} diff --git a/Swiften/StringCodecs/MD5.h b/Swiften/StringCodecs/MD5.h deleted file mode 100644 index 48d62af..0000000 --- a/Swiften/StringCodecs/MD5.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2010-2012 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#pragma once - -#include <Swiften/Base/API.h> -#include <Swiften/Base/ByteArray.h> -#include <Swiften/Base/SafeByteArray.h> - -namespace Swift { -	struct md5_state_s; - -	class SWIFTEN_API MD5 { -		public: -			MD5(); -			~MD5(); - -			MD5& update(const std::vector<unsigned char>& data); -			std::vector<unsigned char> getHash(); - -			static ByteArray getHash(const ByteArray& data); -			static ByteArray getHash(const SafeByteArray& data); -			static bool isAllowedForCrypto(); - -		private: -			md5_state_s* state; -	}; -} diff --git a/Swiften/StringCodecs/PBKDF2.h b/Swiften/StringCodecs/PBKDF2.h index 0c04145..ae0bb17 100644 --- a/Swiften/StringCodecs/PBKDF2.h +++ b/Swiften/StringCodecs/PBKDF2.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -8,18 +8,17 @@  #include <Swiften/Base/SafeByteArray.h>  #include <Swiften/Base/Concat.h> +#include <Swiften/Crypto/CryptoProvider.h>  namespace Swift {  	class PBKDF2 {  		public: -			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))); +			static ByteArray encode(const SafeByteArray& password, const ByteArray& salt, int iterations, CryptoProvider* crypto) { +				ByteArray u = crypto->getHMACSHA1(password, concat(salt, createByteArray("\0\0\0\1", 4)));  				ByteArray result(u);  				int i = 1;  				while (i < iterations) { -					u = prf(password, u); +					u = crypto->getHMACSHA1(password, u);  					for (unsigned int j = 0; j < u.size(); ++j) {  						result[j] ^= u[j];  					} diff --git a/Swiften/StringCodecs/SHA1.cpp b/Swiften/StringCodecs/SHA1.cpp deleted file mode 100644 index 8b03989..0000000 --- a/Swiften/StringCodecs/SHA1.cpp +++ /dev/null @@ -1,224 +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/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> -100% Public Domain - -Test Vectors (from FIPS PUB 180-1) -"abc" -	A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D -"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" -	84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 -A million repetitions of "a" -	34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F -*/ - -/* #define LITTLE_ENDIAN * This should be #define'd if true. */ -/* #define SHA1HANDSOFF * Copies data before messing with it. */ - -#include <stdio.h> -#include <string.h> - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -/* blk0() and blk() perform the initial expand. */ -/* I got the idea of expanding during the round function from SSLeay */ -#ifdef SWIFTEN_LITTLE_ENDIAN -#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ -		|(rol(block->l[i],8)&0x00FF00FF)) -#else -#define blk0(i) block->l[i] -#endif -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ -		^block->l[(i+2)&15]^block->l[i&15],1)) - -/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); - - -/* Hash a single 512-bit block. This is the core of the algorithm. */ - -void SHA1::Transform(boost::uint32_t state[5], boost::uint8_t buffer[64]) -{ -boost::uint32_t a, b, c, d, e; -typedef union { -		boost::uint8_t c[64]; -		boost::uint32_t l[16]; -} CHAR64LONG16; -CHAR64LONG16* block; -#ifdef SHA1HANDSOFF -static boost::uint8_t workspace[64]; -		block = (CHAR64LONG16*)workspace; -		memcpy(block, buffer, 64); -#else -		block = reinterpret_cast<CHAR64LONG16*>(buffer); -#endif -		/* Copy context->state[] to working vars */ -		a = state[0]; -		b = state[1]; -		c = state[2]; -		d = state[3]; -		e = state[4]; -		/* 4 rounds of 20 operations each. Loop unrolled. */ -		R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); -		R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); -		R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); -		R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); -		R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); -		R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); -		R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); -		R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); -		R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); -		R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); -		R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); -		R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); -		R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); -		R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); -		R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); -		R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); -		R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); -		R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); -		R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); -		R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); -		/* Add the working vars back into context.state[] */ -		state[0] += a; -		state[1] += b; -		state[2] += c; -		state[3] += d; -		state[4] += e; -		/* Wipe variables */ -		a = b = c = d = e = 0; -} - - -/* SHA1Init - Initialize new context */ - -void SHA1::Init(SHA1::CTX* context) -{ -		/* SHA1 initialization constants */ -		context->state[0] = 0x67452301; -		context->state[1] = 0xEFCDAB89; -		context->state[2] = 0x98BADCFE; -		context->state[3] = 0x10325476; -		context->state[4] = 0xC3D2E1F0; -		context->count[0] = context->count[1] = 0; -} - - -/* Run your data through this. */ - -void SHA1::Update(SHA1::CTX* context, boost::uint8_t* data, unsigned int len) -{ -unsigned int i, j; - -		j = (context->count[0] >> 3) & 63; -		if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; -		context->count[1] += (len >> 29); -		if ((j + len) > 63) { -				memcpy(&context->buffer[j], data, (i = 64-j)); -				Transform(context->state, context->buffer); -				for ( ; i + 63 < len; i += 64) { -						Transform(context->state, &data[i]); -				} -				j = 0; -		} -		else i = 0; -		memcpy(&context->buffer[j], &data[i], len - i); -} - - -/* Add padding and return the message digest. */ - -void SHA1::Final(boost::uint8_t digest[20], SHA1::CTX* context) -{ -boost::uint32_t i, j; -boost::uint8_t finalcount[8]; - -		for (i = 0; i < 8; i++) { -				finalcount[i] = (boost::uint8_t) ((context->count[(i >= 4 ? 0 : 1)] -				 >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */ -		} -		Update(context, (boost::uint8_t *)("\200"), 1); -		while ((context->count[0] & 504) != 448) { -				Update(context, (boost::uint8_t *)("\0"), 1); -		} -		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); -		} -		/* Wipe variables */ -		i = j = 0; -		memset(context->buffer, 0, 64); -		memset(context->state, 0, 20); -		memset(context->count, 0, 8); -		memset(&finalcount, 0, 8); -#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */ -		Transform(context->state, context->buffer); -#endif -} - -// ----------------------------------------------------------------------------- - -namespace Swift { - -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), static_cast<unsigned int>(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), static_cast<unsigned int>(inputCopy.size())); - -	ByteArray digest; -	digest.resize(20); -	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 deleted file mode 100644 index 30e757c..0000000 --- a/Swiften/StringCodecs/SHA1.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2010-2012 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#pragma once - -#ifdef SWIFTEN_PLATFORM_WIN32 -#include "SHA1_Windows.h" -#else - -#include <vector> -#include <boost/cstdint.hpp> - -#include <Swiften/Base/API.h> -#include <Swiften/Base/ByteArray.h> -#include <Swiften/Base/SafeByteArray.h> - -namespace Swift { -	class SWIFTEN_API 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; -	}; -} - -#endif diff --git a/Swiften/StringCodecs/SHA256.cpp b/Swiften/StringCodecs/SHA256.cpp deleted file mode 100644 index 6e3c4ec..0000000 --- a/Swiften/StringCodecs/SHA256.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* - * 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" -#pragma clang diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wunused-macros" -#pragma clang diagnostic ignored "-Wdisabled-macro-expansion" - -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 deleted file mode 100644 index fe60f2e..0000000 --- a/Swiften/StringCodecs/SHA256.h +++ /dev/null @@ -1,57 +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 <vector> -#include <boost/cstdint.hpp> - -#include <Swiften/Base/API.h> -#include <Swiften/Base/ByteArray.h> -#include <Swiften/Base/SafeByteArray.h> - -namespace Swift { -	class SWIFTEN_API 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/HMACTest.cpp b/Swiften/StringCodecs/UnitTest/HMACTest.cpp deleted file mode 100644 index 50b1330..0000000 --- a/Swiften/StringCodecs/UnitTest/HMACTest.cpp +++ /dev/null @@ -1,49 +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 <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/MD5Test.cpp b/Swiften/StringCodecs/UnitTest/MD5Test.cpp deleted file mode 100644 index c62c46a..0000000 --- a/Swiften/StringCodecs/UnitTest/MD5Test.cpp +++ /dev/null @@ -1,49 +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 <QA/Checker/IO.h> - -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/extensions/TestFactoryRegistry.h> - -#include <Swiften/StringCodecs/MD5.h> -#include <Swiften/Base/ByteArray.h> - -using namespace Swift; - -class MD5Test : public CppUnit::TestFixture { -		CPPUNIT_TEST_SUITE(MD5Test); -		CPPUNIT_TEST(testGetHash_Empty); -		CPPUNIT_TEST(testGetHash_Alphabet); -		CPPUNIT_TEST(testIncrementalTest); -		CPPUNIT_TEST_SUITE_END(); - -	public: -		void testGetHash_Empty() { -			ByteArray result(MD5::getHash(createByteArray(""))); - -			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(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"))); - -			CPPUNIT_ASSERT_EQUAL(createByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result); -		} - -		void testIncrementalTest() { -			MD5 testling; -			testling.update(createByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); -			testling.update(createByteArray("abcdefghijklmnopqrstuvwxyz0123456789")); - -			ByteArray result = testling.getHash(); - -			CPPUNIT_ASSERT_EQUAL(createByteArray("\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f", 16), result); -		} -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(MD5Test); diff --git a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp index 608ca62..1172679 100644 --- a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp +++ b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -12,7 +12,8 @@  #include <Swiften/Base/ByteArray.h>  #include <Swiften/StringCodecs/PBKDF2.h> -#include <Swiften/StringCodecs/HMAC_SHA1.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -24,23 +25,30 @@ class PBKDF2Test : public CppUnit::TestFixture {  		CPPUNIT_TEST_SUITE_END();  	public: +		void setUp() { +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); +		} +  		void testGetResult_I1() { -			ByteArray result(PBKDF2::encode<HMAC_SHA1 >(createSafeByteArray("password"), createByteArray("salt"), 1)); +			ByteArray result(PBKDF2::encode(createSafeByteArray("password"), createByteArray("salt"), 1, crypto.get()));  			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<HMAC_SHA1 >(createSafeByteArray("password"), createByteArray("salt"), 2)); +			ByteArray result(PBKDF2::encode(createSafeByteArray("password"), createByteArray("salt"), 2, crypto.get()));  			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<HMAC_SHA1 >(createSafeByteArray("password"), createByteArray("salt"), 4096)); +			ByteArray result(PBKDF2::encode(createSafeByteArray("password"), createByteArray("salt"), 4096, crypto.get()));  			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);  		} +	 +	private: +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(PBKDF2Test); diff --git a/Swiften/StringCodecs/UnitTest/SHA1Test.cpp b/Swiften/StringCodecs/UnitTest/SHA1Test.cpp deleted file mode 100644 index cb1a6f4..0000000 --- a/Swiften/StringCodecs/UnitTest/SHA1Test.cpp +++ /dev/null @@ -1,93 +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 <QA/Checker/IO.h> - -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/extensions/TestFactoryRegistry.h> - -#include <Swiften/StringCodecs/SHA1.h> - -using namespace Swift; - -class SHA1Test : public CppUnit::TestFixture { -		CPPUNIT_TEST_SUITE(SHA1Test); -		CPPUNIT_TEST(testGetHash); -		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() { -			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 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(createByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"), result); -		} - -		void testGetHashStatic_NoData() { -			ByteArray result(SHA1::getHash(ByteArray())); - -			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); -		} -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(SHA1Test); diff --git a/Swiften/StringCodecs/UnitTest/SHA256Test.cpp b/Swiften/StringCodecs/UnitTest/SHA256Test.cpp deleted file mode 100644 index 5bcdd11..0000000 --- a/Swiften/StringCodecs/UnitTest/SHA256Test.cpp +++ /dev/null @@ -1,41 +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 <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); diff --git a/Swiften/TLS/Certificate.cpp b/Swiften/TLS/Certificate.cpp index a796463..ec268c8 100644 --- a/Swiften/TLS/Certificate.cpp +++ b/Swiften/TLS/Certificate.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -8,7 +8,7 @@  #include <sstream> -#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/Crypto/CryptoProvider.h>  #include <Swiften/StringCodecs/Hexify.h>  namespace Swift { @@ -19,8 +19,8 @@ const char* Certificate::ID_ON_DNSSRV_OID = "1.3.6.1.5.5.7.8.7";  Certificate::~Certificate() {  } -std::string Certificate::getSHA1Fingerprint() const { -	ByteArray hash = SHA1::getHash(toDER()); +std::string Certificate::getSHA1Fingerprint(Certificate::ref certificate, CryptoProvider* crypto) { +	ByteArray hash = crypto->getSHA1Hash(certificate->toDER());  	std::ostringstream s;  	for (size_t i = 0; i < hash.size(); ++i) {  		if (i > 0) { diff --git a/Swiften/TLS/Certificate.h b/Swiften/TLS/Certificate.h index 9aec86c..f558c12 100644 --- a/Swiften/TLS/Certificate.h +++ b/Swiften/TLS/Certificate.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -13,6 +13,8 @@  #include <Swiften/Base/ByteArray.h>  namespace Swift { +	class CryptoProvider; +  	class SWIFTEN_API Certificate {  		public:  			typedef boost::shared_ptr<Certificate> ref; @@ -32,7 +34,7 @@ namespace Swift {  			virtual ByteArray toDER() const = 0; -			virtual std::string getSHA1Fingerprint() const; +			static std::string getSHA1Fingerprint(Certificate::ref, CryptoProvider* crypto);  		protected:  			static const char* ID_ON_XMPPADDR_OID; diff --git a/Swiften/TLS/UnitTest/CertificateTest.cpp b/Swiften/TLS/UnitTest/CertificateTest.cpp index 5df5639..3352118 100644 --- a/Swiften/TLS/UnitTest/CertificateTest.cpp +++ b/Swiften/TLS/UnitTest/CertificateTest.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -12,6 +12,8 @@  #include <Swiften/TLS/Certificate.h>  #include <Swiften/TLS/SimpleCertificate.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -25,7 +27,7 @@ class CertificateTest : public CppUnit::TestFixture {  			SimpleCertificate::ref testling = boost::make_shared<SimpleCertificate>();  			testling->setDER(createByteArray("abcdefg")); -			CPPUNIT_ASSERT_EQUAL(std::string("2f:b5:e1:34:19:fc:89:24:68:65:e7:a3:24:f4:76:ec:62:4e:87:40"), testling->getSHA1Fingerprint()); +			CPPUNIT_ASSERT_EQUAL(std::string("2f:b5:e1:34:19:fc:89:24:68:65:e7:a3:24:f4:76:ec:62:4e:87:40"), Certificate::getSHA1Fingerprint(testling, boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()).get()));  		}  }; diff --git a/Swiften/VCards/UnitTest/VCardManagerTest.cpp b/Swiften/VCards/UnitTest/VCardManagerTest.cpp index eecec7b..9f1c8bb 100644 --- a/Swiften/VCards/UnitTest/VCardManagerTest.cpp +++ b/Swiften/VCards/UnitTest/VCardManagerTest.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -16,6 +16,8 @@  #include <Swiften/VCards/VCardMemoryStorage.h>  #include <Swiften/Queries/IQRouter.h>  #include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Crypto/CryptoProvider.h> +#include <Swiften/Crypto/PlatformCryptoProvider.h>  using namespace Swift; @@ -36,9 +38,10 @@ class VCardManagerTest : public CppUnit::TestFixture {  	public:  		void setUp() {  			ownJID = JID("baz@fum.com/dum"); +			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());  			stanzaChannel = new DummyStanzaChannel();  			iqRouter = new IQRouter(stanzaChannel); -			vcardStorage = new VCardMemoryStorage(); +			vcardStorage = new VCardMemoryStorage(crypto.get());  		}  		void tearDown() { @@ -201,6 +204,7 @@ class VCardManagerTest : public CppUnit::TestFixture {  		VCardMemoryStorage* vcardStorage;  		std::vector< std::pair<JID, VCard::ref> > changes;  		std::vector<VCard::ref> ownChanges; +		boost::shared_ptr<CryptoProvider> crypto;  };  CPPUNIT_TEST_SUITE_REGISTRATION(VCardManagerTest); diff --git a/Swiften/VCards/VCardMemoryStorage.h b/Swiften/VCards/VCardMemoryStorage.h index ade9c89..86ae1b2 100644 --- a/Swiften/VCards/VCardMemoryStorage.h +++ b/Swiften/VCards/VCardMemoryStorage.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -15,7 +15,7 @@  namespace Swift {  	class VCardMemoryStorage : public VCardStorage {  		public: -			VCardMemoryStorage() {} +			VCardMemoryStorage(CryptoProvider* crypto) : VCardStorage(crypto) {}  			virtual VCard::ref getVCard(const JID& jid) const {  				VCardMap::const_iterator i = vcards.find(jid); diff --git a/Swiften/VCards/VCardStorage.cpp b/Swiften/VCards/VCardStorage.cpp index 900f1e5..fefea83 100644 --- a/Swiften/VCards/VCardStorage.cpp +++ b/Swiften/VCards/VCardStorage.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -7,17 +7,20 @@  #include <Swiften/VCards/VCardStorage.h>  #include <Swiften/StringCodecs/Hexify.h> -#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/Crypto/CryptoProvider.h>  namespace Swift { +VCardStorage::VCardStorage(CryptoProvider* crypto) : crypto(crypto) { +} +  VCardStorage::~VCardStorage() {  }  std::string VCardStorage::getPhotoHash(const JID& jid) const {  	VCard::ref vCard = getVCard(jid);  	if (vCard && !vCard->getPhoto().empty()) { -		return Hexify::hexify(SHA1::getHash(vCard->getPhoto())); +		return Hexify::hexify(crypto->getSHA1Hash(vCard->getPhoto()));  	}  	else {  		return ""; diff --git a/Swiften/VCards/VCardStorage.h b/Swiften/VCards/VCardStorage.h index 5fba915..924204c 100644 --- a/Swiften/VCards/VCardStorage.h +++ b/Swiften/VCards/VCardStorage.h @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ @@ -14,14 +14,19 @@  namespace Swift {  	class JID; +	class CryptoProvider;  	class SWIFTEN_API VCardStorage {  		public: +			VCardStorage(CryptoProvider*);  			virtual ~VCardStorage();  			virtual VCard::ref getVCard(const JID& jid) const = 0;  			virtual void setVCard(const JID&, VCard::ref) = 0;  			virtual std::string getPhotoHash(const JID&) const; + +		private: +			CryptoProvider* crypto;  	};  } | 
 Swift
 Swift