diff options
Diffstat (limited to 'Swiften')
104 files changed, 1475 insertions, 1753 deletions
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; }; } |