summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2011-05-18 13:45:41 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-05-18 14:24:28 (GMT)
commit23fa0f462ddd0c686c677bfe5d4d743621432b7e (patch)
treeb8f0ea1860640f89eafba2460cc5d45bf28fc77c /Swiften
parent2456a8b12163b3249b6b9164b601c36772eb05a1 (diff)
downloadswift-23fa0f462ddd0c686c677bfe5d4d743621432b7e.zip
swift-23fa0f462ddd0c686c677bfe5d4d743621432b7e.tar.bz2
Introduce safe containers for storing passwords.
Diffstat (limited to 'Swiften')
-rw-r--r--Swiften/Base/Algorithm.h9
-rw-r--r--Swiften/Base/ByteArray.cpp12
-rw-r--r--Swiften/Base/ByteArray.h11
-rw-r--r--Swiften/Base/SConscript2
-rw-r--r--Swiften/Base/SafeAllocator.h30
-rw-r--r--Swiften/Base/SafeByteArray.cpp27
-rw-r--r--Swiften/Base/SafeByteArray.h39
-rw-r--r--Swiften/Base/SafeString.cpp17
-rw-r--r--Swiften/Base/SafeString.h65
-rw-r--r--Swiften/Client/Client.cpp2
-rw-r--r--Swiften/Client/Client.h2
-rw-r--r--Swiften/Client/ClientSession.cpp9
-rw-r--r--Swiften/Client/ClientSession.h3
-rw-r--r--Swiften/Client/CoreClient.cpp4
-rw-r--r--Swiften/Client/CoreClient.h6
-rw-r--r--Swiften/Client/UnitTest/ClientSessionTest.cpp1
-rw-r--r--Swiften/Elements/AuthRequest.h13
-rw-r--r--Swiften/Elements/AuthResponse.h13
-rw-r--r--Swiften/IDN/StringPrep.cpp51
-rw-r--r--Swiften/IDN/StringPrep.h2
-rw-r--r--Swiften/Parser/AuthRequestParser.cpp2
-rw-r--r--Swiften/Parser/AuthResponseParser.cpp2
-rw-r--r--Swiften/SASL/ClientAuthenticator.h15
-rw-r--r--Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp12
-rw-r--r--Swiften/SASL/DIGESTMD5ClientAuthenticator.h3
-rw-r--r--Swiften/SASL/PLAINClientAuthenticator.cpp4
-rw-r--r--Swiften/SASL/PLAINClientAuthenticator.h2
-rw-r--r--Swiften/SASL/PLAINMessage.cpp12
-rw-r--r--Swiften/SASL/PLAINMessage.h12
-rw-r--r--Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp12
-rw-r--r--Swiften/SASL/SCRAMSHA1ClientAuthenticator.h2
-rw-r--r--Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp9
-rw-r--r--Swiften/SASL/UnitTest/PLAINClientAuthenticatorTest.cpp4
-rw-r--r--Swiften/SASL/UnitTest/PLAINMessageTest.cpp20
-rw-r--r--Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp37
-rw-r--r--Swiften/Serializer/AuthRequestSerializer.cpp9
-rw-r--r--Swiften/Serializer/AuthResponseSerializer.cpp9
-rw-r--r--Swiften/Serializer/UnitTest/AuthRequestSerializerTest.cpp4
-rw-r--r--Swiften/Serializer/UnitTest/AuthResponseSerializerTest.cpp4
-rw-r--r--Swiften/Server/ServerFromClientSession.cpp2
-rw-r--r--Swiften/Server/SimpleUserRegistry.cpp6
-rw-r--r--Swiften/Server/SimpleUserRegistry.h4
-rw-r--r--Swiften/Server/UserRegistry.h4
-rw-r--r--Swiften/StringCodecs/Base64.cpp68
-rw-r--r--Swiften/StringCodecs/Base64.h3
-rw-r--r--Swiften/StringCodecs/HMACSHA1.cpp54
-rw-r--r--Swiften/StringCodecs/HMACSHA1.h2
-rw-r--r--Swiften/StringCodecs/MD5.cpp27
-rw-r--r--Swiften/StringCodecs/MD5.h2
-rw-r--r--Swiften/StringCodecs/PBKDF2.cpp2
-rw-r--r--Swiften/StringCodecs/PBKDF2.h4
-rw-r--r--Swiften/StringCodecs/SHA1.cpp14
-rw-r--r--Swiften/StringCodecs/SHA1.h5
-rw-r--r--Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp2
-rw-r--r--Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp6
55 files changed, 484 insertions, 213 deletions
diff --git a/Swiften/Base/Algorithm.h b/Swiften/Base/Algorithm.h
index 4d7f1de..4694823 100644
--- a/Swiften/Base/Algorithm.h
+++ b/Swiften/Base/Algorithm.h
@@ -88,8 +88,8 @@ namespace Swift {
Detail::eraseIfImpl(container, predicate, typename Detail::ContainerTraits<C>::Category());
}
- template<typename C>
- void append(C& target, const C& source) {
+ template<typename Source, typename Target>
+ void append(Target& target, const Source& source) {
target.insert(target.end(), source.begin(), source.end());
}
@@ -104,6 +104,11 @@ namespace Swift {
}
}
+ template<typename Container>
+ void nullify(Container& c) {
+ std::fill(c.begin(), c.end(), 0);
+ }
+
/*
* Functors
*/
diff --git a/Swiften/Base/ByteArray.cpp b/Swiften/Base/ByteArray.cpp
index 10da395..6be96aa 100644
--- a/Swiften/Base/ByteArray.cpp
+++ b/Swiften/Base/ByteArray.cpp
@@ -36,18 +36,6 @@ std::vector<unsigned char> createByteArray(const char* c) {
return data;
}
-std::vector<unsigned char> createByteArray(const char* c, size_t n) {
- std::vector<unsigned char> data(n);
- std::copy(c, c + n, data.begin());
- return data;
-}
-
-std::vector<unsigned char> createByteArray(const unsigned char* c, size_t n) {
- std::vector<unsigned char> data(n);
- std::copy(c, c + n, data.begin());
- return data;
-}
-
std::string byteArrayToString(const ByteArray& b) {
size_t i;
for (i = b.size(); i > 0; --i) {
diff --git a/Swiften/Base/ByteArray.h b/Swiften/Base/ByteArray.h
index 8ef8dd6..b368ef8 100644
--- a/Swiften/Base/ByteArray.h
+++ b/Swiften/Base/ByteArray.h
@@ -12,16 +12,21 @@
namespace Swift {
typedef std::vector<unsigned char> ByteArray;
- ByteArray createByteArray(const unsigned char* c, size_t n);
ByteArray createByteArray(const std::string& s);
ByteArray createByteArray(const char* c);
- ByteArray createByteArray(const char* c, size_t n);
+
+ inline ByteArray createByteArray(const unsigned char* c, size_t n) {
+ return ByteArray(c, c + n);
+ }
+
+ inline ByteArray createByteArray(const char* c, size_t n) {
+ return ByteArray(c, c + n);
+ }
inline ByteArray createByteArray(char c) {
return std::vector<unsigned char>(1, c);
}
-
template<typename T, typename A>
static const T* vecptr(const std::vector<T, A>& v) {
return v.empty() ? NULL : &v[0];
diff --git a/Swiften/Base/SConscript b/Swiften/Base/SConscript
index 01252e5..ab78639 100644
--- a/Swiften/Base/SConscript
+++ b/Swiften/Base/SConscript
@@ -2,10 +2,12 @@ Import("swiften_env")
objects = swiften_env.SwiftenObject([
"ByteArray.cpp",
+ "SafeByteArray.cpp",
"Error.cpp",
"Log.cpp",
"Paths.cpp",
"String.cpp",
+ "SafeString.cpp",
"IDGenerator.cpp",
"sleep.cpp",
])
diff --git a/Swiften/Base/SafeAllocator.h b/Swiften/Base/SafeAllocator.h
new file mode 100644
index 0000000..fc74234
--- /dev/null
+++ b/Swiften/Base/SafeAllocator.h
@@ -0,0 +1,30 @@
+/*
+ * 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 <vector>
+#include <algorithm>
+
+namespace Swift {
+ template<typename T>
+ class SafeAllocator : public std::allocator<T> {
+ public:
+ template <class U> struct rebind {
+ typedef SafeAllocator<U> other;
+ };
+
+ SafeAllocator() throw() {}
+ SafeAllocator(const SafeAllocator&) throw() : std::allocator<T>() {}
+ template <class U> SafeAllocator(const SafeAllocator<U>&) throw() {}
+ ~SafeAllocator() throw() {}
+
+ void deallocate (T* p, size_t num) {
+ std::fill(p, p + num, 0);
+ std::allocator<T>::deallocate(p, num);
+ }
+ };
+};
diff --git a/Swiften/Base/SafeByteArray.cpp b/Swiften/Base/SafeByteArray.cpp
new file mode 100644
index 0000000..e09a285
--- /dev/null
+++ b/Swiften/Base/SafeByteArray.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Base/SafeByteArray.h>
+#include <Swiften/Base/SafeString.h>
+
+using namespace Swift;
+
+namespace Swift {
+
+SafeByteArray createSafeByteArray(const char* c) {
+ SafeByteArray data;
+ while (*c) {
+ data.push_back(static_cast<unsigned char>(*c));
+ ++c;
+ }
+ return data;
+}
+
+SafeByteArray createSafeByteArray(const SafeString& s) {
+ return SafeByteArray(s.begin(), s.end());
+}
+
+}
diff --git a/Swiften/Base/SafeByteArray.h b/Swiften/Base/SafeByteArray.h
new file mode 100644
index 0000000..c80a2c0
--- /dev/null
+++ b/Swiften/Base/SafeByteArray.h
@@ -0,0 +1,39 @@
+/*
+ * 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 <Swiften/Base/SafeAllocator.h>
+#include <Swiften/Base/ByteArray.h>
+
+namespace Swift {
+ class SafeString;
+
+ typedef std::vector<unsigned char, SafeAllocator<unsigned char> > SafeByteArray;
+
+ inline SafeByteArray createSafeByteArray(const ByteArray& a) {
+ return SafeByteArray(a.begin(), a.end());
+ }
+
+ SafeByteArray createSafeByteArray(const char* c);
+
+ inline SafeByteArray createSafeByteArray(const std::string& s) {
+ return SafeByteArray(s.begin(), s.end());
+ }
+
+ inline SafeByteArray createSafeByteArray(char c) {
+ return SafeByteArray(1, c);
+ }
+
+ inline SafeByteArray createSafeByteArray(const char* c, size_t n) {
+ return SafeByteArray(c, c + n);
+ }
+
+ SafeByteArray createSafeByteArray(const SafeString& s);
+}
+
diff --git a/Swiften/Base/SafeString.cpp b/Swiften/Base/SafeString.cpp
new file mode 100644
index 0000000..2abcdb0
--- /dev/null
+++ b/Swiften/Base/SafeString.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Base/SafeString.h>
+
+#include <algorithm>
+
+using namespace Swift;
+
+SafeString::SafeString(const char* rawData) {
+ for (const char* c = rawData; *c; ++c) {
+ data.push_back(*c);
+ }
+}
diff --git a/Swiften/Base/SafeString.h b/Swiften/Base/SafeString.h
new file mode 100644
index 0000000..0bd898d
--- /dev/null
+++ b/Swiften/Base/SafeString.h
@@ -0,0 +1,65 @@
+/*
+ * 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 <vector>
+#include <string>
+
+#include <Swiften/Base/SafeAllocator.h>
+
+namespace Swift {
+ class SafeString {
+ public:
+ typedef std::vector<char, SafeAllocator<char> > Data;
+ typedef Data::iterator Iterator;
+ typedef Data::const_iterator ConstIterator;
+
+ SafeString() {
+ }
+
+ SafeString(const std::string& s) : data(s.begin(), s.end()) {
+ }
+
+ SafeString(const char*);
+
+
+ std::string toString() const {
+ return data.empty() ? std::string() : std::string(&data[0], data.size());
+ }
+
+ void resize(size_t n) {
+ data.resize(n);
+ }
+
+ char& operator[](size_t n) {
+ return data[n];
+ }
+
+ Iterator begin() {
+ return data.begin();
+ }
+
+ Iterator end() {
+ return data.end();
+ }
+
+ ConstIterator begin() const {
+ return data.begin();
+ }
+
+ ConstIterator end() const {
+ return data.end();
+ }
+
+ size_t size() const {
+ return data.size();
+ }
+
+ private:
+ std::vector<char, SafeAllocator<char> > data;
+ };
+};
diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index 13071ac..c53bcaf 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -29,7 +29,7 @@
namespace Swift {
-Client::Client(const JID& jid, const std::string& password, NetworkFactories* networkFactories, Storages* storages) : CoreClient(jid, password, networkFactories), storages(storages) {
+Client::Client(const JID& jid, const SafeString& password, NetworkFactories* networkFactories, Storages* storages) : CoreClient(jid, password, networkFactories), storages(storages) {
memoryStorages = new MemoryStorages();
softwareVersionResponder = new SoftwareVersionResponder(getIQRouter());
diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h
index 05c1e6e..bee9d5c 100644
--- a/Swiften/Client/Client.h
+++ b/Swiften/Client/Client.h
@@ -47,7 +47,7 @@ namespace Swift {
* this is NULL,
* all data will be stored in memory (and be lost on shutdown)
*/
- Client(const JID& jid, const std::string& password, NetworkFactories* networkFactories, Storages* storages = NULL);
+ Client(const JID& jid, const SafeString& password, NetworkFactories* networkFactories, Storages* storages = NULL);
~Client();
diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp
index 846a5e7..57d9c12 100644
--- a/Swiften/Client/ClientSession.cpp
+++ b/Swiften/Client/ClientSession.cpp
@@ -12,6 +12,7 @@
#include <boost/uuid/uuid_generators.hpp>
#include <boost/smart_ptr/make_shared.hpp>
+#include <Swiften/Base/SafeString.h>
#include <Swiften/Elements/ProtocolHeader.h>
#include <Swiften/Elements/StreamFeatures.h>
#include <Swiften/Elements/StreamError.h>
@@ -185,7 +186,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
if (stream->hasTLSCertificate()) {
if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) {
state = Authenticating;
- stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createByteArray("")));
+ stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createSafeByteArray("")));
}
else {
finishSession(Error::TLSClientCertificateError);
@@ -193,7 +194,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
}
else if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) {
state = Authenticating;
- stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createByteArray("")));
+ stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createSafeByteArray("")));
}
else if (streamFeatures->hasAuthenticationMechanism("SCRAM-SHA-1") || streamFeatures->hasAuthenticationMechanism("SCRAM-SHA-1-PLUS")) {
std::ostringstream s;
@@ -275,6 +276,8 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
else if (AuthSuccess* authSuccess = dynamic_cast<AuthSuccess*>(element.get())) {
checkState(Authenticating);
if (authenticator && !authenticator->setChallenge(authSuccess->getValue())) {
+ delete authenticator;
+ authenticator = NULL;
finishSession(Error::ServerVerificationFailedError);
}
else {
@@ -336,7 +339,7 @@ bool ClientSession::checkState(State state) {
return true;
}
-void ClientSession::sendCredentials(const std::string& password) {
+void ClientSession::sendCredentials(const SafeString& password) {
assert(WaitingForCredentials);
state = Authenticating;
authenticator->setCredentials(localJID.getNode(), password);
diff --git a/Swiften/Client/ClientSession.h b/Swiften/Client/ClientSession.h
index 9022b16..246388a 100644
--- a/Swiften/Client/ClientSession.h
+++ b/Swiften/Client/ClientSession.h
@@ -21,6 +21,7 @@
namespace Swift {
class ClientAuthenticator;
class CertificateTrustChecker;
+ class SafeString;
class ClientSession : public boost::enable_shared_from_this<ClientSession> {
public:
@@ -104,7 +105,7 @@ namespace Swift {
return getState() == Finished;
}
- void sendCredentials(const std::string& password);
+ void sendCredentials(const SafeString& password);
void sendStanza(boost::shared_ptr<Stanza>);
void setCertificateTrustChecker(CertificateTrustChecker* checker) {
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index a17696f..9521bd9 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -27,7 +27,7 @@
namespace Swift {
-CoreClient::CoreClient(const JID& jid, const std::string& password, NetworkFactories* networkFactories) : jid_(jid), password_(password), networkFactories(networkFactories), disconnectRequested_(false), certificateTrustChecker(NULL) {
+CoreClient::CoreClient(const JID& jid, const SafeString& password, NetworkFactories* networkFactories) : jid_(jid), password_(password), networkFactories(networkFactories), disconnectRequested_(false), certificateTrustChecker(NULL) {
stanzaChannel_ = new ClientSessionStanzaChannel();
stanzaChannel_->onMessageReceived.connect(boost::bind(&CoreClient::handleMessageReceived, this, _1));
stanzaChannel_->onPresenceReceived.connect(boost::bind(&CoreClient::handlePresenceReceived, this, _1));
@@ -97,7 +97,7 @@ void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connectio
assert(!sessionStream_);
sessionStream_ = boost::make_shared<BasicSessionStream>(ClientStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), tlsFactories->getTLSContextFactory(), networkFactories->getTimerFactory());
if (!certificate_.empty()) {
- sessionStream_->setTLSCertificate(PKCS12Certificate(certificate_, password_));
+ sessionStream_->setTLSCertificate(PKCS12Certificate(certificate_, password_.toString()));
}
sessionStream_->onDataRead.connect(boost::bind(&CoreClient::handleDataRead, this, _1));
sessionStream_->onDataWritten.connect(boost::bind(&CoreClient::handleDataWritten, this, _1));
diff --git a/Swiften/Client/CoreClient.h b/Swiften/Client/CoreClient.h
index 7c46fe7..6dc8392 100644
--- a/Swiften/Client/CoreClient.h
+++ b/Swiften/Client/CoreClient.h
@@ -14,6 +14,7 @@
#include <Swiften/JID/JID.h>
#include <Swiften/Client/ClientError.h>
#include <Swiften/Client/ClientOptions.h>
+#include <Swiften/Base/SafeString.h>
namespace Swift {
class ChainedConnector;
@@ -33,6 +34,7 @@ namespace Swift {
class CertificateTrustChecker;
class NetworkFactories;
class ClientSessionStanzaChannel;
+ class SafeString;
/**
* The central class for communicating with an XMPP server.
@@ -50,7 +52,7 @@ namespace Swift {
* Constructs a client for the given JID with the given password.
* The given eventLoop will be used to post events to.
*/
- CoreClient(const JID& jid, const std::string& password, NetworkFactories* networkFactories);
+ CoreClient(const JID& jid, const SafeString& password, NetworkFactories* networkFactories);
~CoreClient();
void setCertificate(const std::string& certificate);
@@ -200,7 +202,7 @@ namespace Swift {
private:
JID jid_;
- std::string password_;
+ SafeString password_;
NetworkFactories* networkFactories;
ClientSessionStanzaChannel* stanzaChannel_;
IQRouter* iqRouter_;
diff --git a/Swiften/Client/UnitTest/ClientSessionTest.cpp b/Swiften/Client/UnitTest/ClientSessionTest.cpp
index 25476c0..6918be8 100644
--- a/Swiften/Client/UnitTest/ClientSessionTest.cpp
+++ b/Swiften/Client/UnitTest/ClientSessionTest.cpp
@@ -11,6 +11,7 @@
#include <boost/optional.hpp>
#include <boost/smart_ptr/make_shared.hpp>
+#include <Swiften/Base/SafeString.h>
#include <Swiften/Session/SessionStream.h>
#include <Swiften/Client/ClientSession.h>
#include <Swiften/Elements/Message.h>
diff --git a/Swiften/Elements/AuthRequest.h b/Swiften/Elements/AuthRequest.h
index 5e4e4ab..bfc86c2 100644
--- a/Swiften/Elements/AuthRequest.h
+++ b/Swiften/Elements/AuthRequest.h
@@ -11,6 +11,7 @@
#include <boost/optional.hpp>
#include <Swiften/Elements/Element.h>
+#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
class AuthRequest : public Element {
@@ -18,20 +19,20 @@ namespace Swift {
AuthRequest(const std::string& mechanism = "") : mechanism_(mechanism) {
}
- AuthRequest(const std::string& mechanism, const std::vector<unsigned char>& message) :
+ AuthRequest(const std::string& mechanism, const SafeByteArray& message) :
mechanism_(mechanism), message_(message) {
}
- AuthRequest(const std::string& mechanism, const boost::optional<std::vector<unsigned char> >& message) :
+ AuthRequest(const std::string& mechanism, const boost::optional<SafeByteArray>& message) :
mechanism_(mechanism), message_(message) {
}
- const boost::optional<std::vector<unsigned char> >& getMessage() const {
+ const boost::optional<SafeByteArray>& getMessage() const {
return message_;
}
- void setMessage(const std::vector<unsigned char>& message) {
- message_ = boost::optional<std::vector<unsigned char> >(message);
+ void setMessage(const SafeByteArray& message) {
+ message_ = boost::optional<SafeByteArray>(message);
}
const std::string& getMechanism() const {
@@ -44,6 +45,6 @@ namespace Swift {
private:
std::string mechanism_;
- boost::optional<std::vector<unsigned char> > message_;
+ boost::optional<SafeByteArray> message_;
};
}
diff --git a/Swiften/Elements/AuthResponse.h b/Swiften/Elements/AuthResponse.h
index a616005..db2dcea 100644
--- a/Swiften/Elements/AuthResponse.h
+++ b/Swiften/Elements/AuthResponse.h
@@ -10,6 +10,7 @@
#include <boost/optional.hpp>
#include <Swiften/Elements/Element.h>
+#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
class AuthResponse : public Element {
@@ -17,21 +18,21 @@ namespace Swift {
AuthResponse() {
}
- AuthResponse(const std::vector<unsigned char>& value) : value(value) {
+ AuthResponse(const SafeByteArray& value) : value(value) {
}
- AuthResponse(const boost::optional<std::vector<unsigned char> >& value) : value(value) {
+ AuthResponse(const boost::optional<SafeByteArray>& value) : value(value) {
}
- const boost::optional<std::vector<unsigned char> >& getValue() const {
+ const boost::optional<SafeByteArray>& getValue() const {
return value;
}
- void setValue(const std::vector<unsigned char>& value) {
- this->value = boost::optional<std::vector<unsigned char> >(value);
+ void setValue(const SafeByteArray& value) {
+ this->value = boost::optional<SafeByteArray>(value);
}
private:
- boost::optional<std::vector<unsigned char> > value;
+ boost::optional<SafeByteArray> value;
};
}
diff --git a/Swiften/IDN/StringPrep.cpp b/Swiften/IDN/StringPrep.cpp
index 95f294c..f8ebb2c 100644
--- a/Swiften/IDN/StringPrep.cpp
+++ b/Swiften/IDN/StringPrep.cpp
@@ -9,32 +9,45 @@
#include <stringprep.h>
#include <vector>
#include <cassert>
+#include <Swiften/Base/SafeAllocator.h>
-namespace Swift {
+using namespace Swift;
+
+ namespace {
+ static const int MAX_STRINGPREP_SIZE = 1024;
-static const int MAX_STRINGPREP_SIZE = 1024;
+ const Stringprep_profile* getLibIDNProfile(StringPrep::Profile profile) {
+ switch(profile) {
+ case StringPrep::NamePrep: return stringprep_nameprep; break;
+ case StringPrep::XMPPNodePrep: return stringprep_xmpp_nodeprep; break;
+ case StringPrep::XMPPResourcePrep: return stringprep_xmpp_resourceprep; break;
+ case StringPrep::SASLPrep: return stringprep_saslprep; break;
+ }
+ assert(false);
+ return 0;
+ }
-const Stringprep_profile* getLibIDNProfile(StringPrep::Profile profile) {
- switch(profile) {
- case StringPrep::NamePrep: return stringprep_nameprep; break;
- case StringPrep::XMPPNodePrep: return stringprep_xmpp_nodeprep; break;
- case StringPrep::XMPPResourcePrep: return stringprep_xmpp_resourceprep; break;
- case StringPrep::SASLPrep: return stringprep_saslprep; break;
+ template<typename StringType, typename ContainerType>
+ StringType getStringPrepared(const StringType& s, StringPrep::Profile profile) {
+ ContainerType input(s.begin(), s.end());
+ input.resize(MAX_STRINGPREP_SIZE);
+ if (stringprep(&input[0], MAX_STRINGPREP_SIZE, static_cast<Stringprep_profile_flags>(0), getLibIDNProfile(profile)) == 0) {
+ return StringType(&input[0]);
+ }
+ else {
+ return StringType();
+ }
}
- assert(false);
- return 0;
}
+namespace Swift {
+
std::string StringPrep::getPrepared(const std::string& s, Profile profile) {
-
- std::vector<char> input(s.begin(), s.end());
- input.resize(MAX_STRINGPREP_SIZE);
- if (stringprep(&input[0], MAX_STRINGPREP_SIZE, static_cast<Stringprep_profile_flags>(0), getLibIDNProfile(profile)) == 0) {
- return std::string(&input[0]);
- }
- else {
- return "";
- }
+ return getStringPrepared< std::string, std::vector<char> >(s, profile);
+}
+
+SafeString StringPrep::getPrepared(const SafeString& s, Profile profile) {
+ return getStringPrepared<SafeString, std::vector<char, SafeAllocator<char> > >(s, profile);
}
}
diff --git a/Swiften/IDN/StringPrep.h b/Swiften/IDN/StringPrep.h
index f40553b..fc75118 100644
--- a/Swiften/IDN/StringPrep.h
+++ b/Swiften/IDN/StringPrep.h
@@ -7,6 +7,7 @@
#pragma once
#include <string>
+#include <Swiften/Base/SafeString.h>
namespace Swift {
class StringPrep {
@@ -19,5 +20,6 @@ namespace Swift {
};
static std::string getPrepared(const std::string& s, Profile profile);
+ static SafeString getPrepared(const SafeString& s, Profile profile);
};
}
diff --git a/Swiften/Parser/AuthRequestParser.cpp b/Swiften/Parser/AuthRequestParser.cpp
index d5d977f..04d9e4f 100644
--- a/Swiften/Parser/AuthRequestParser.cpp
+++ b/Swiften/Parser/AuthRequestParser.cpp
@@ -22,7 +22,7 @@ void AuthRequestParser::handleStartElement(const std::string&, const std::string
void AuthRequestParser::handleEndElement(const std::string&, const std::string&) {
--depth_;
if (depth_ == 0) {
- getElementGeneric()->setMessage(Base64::decode(text_));
+ getElementGeneric()->setMessage(createSafeByteArray(Base64::decode(text_)));
}
}
diff --git a/Swiften/Parser/AuthResponseParser.cpp b/Swiften/Parser/AuthResponseParser.cpp
index 32d66fe..7f9a530 100644
--- a/Swiften/Parser/AuthResponseParser.cpp
+++ b/Swiften/Parser/AuthResponseParser.cpp
@@ -19,7 +19,7 @@ void AuthResponseParser::handleStartElement(const std::string&, const std::strin
void AuthResponseParser::handleEndElement(const std::string&, const std::string&) {
--depth;
if (depth == 0) {
- getElementGeneric()->setValue(Base64::decode(text));
+ getElementGeneric()->setValue(createSafeByteArray(Base64::decode(text)));
}
}
diff --git a/Swiften/SASL/ClientAuthenticator.h b/Swiften/SASL/ClientAuthenticator.h
index 399a9d5..6557b9a 100644
--- a/Swiften/SASL/ClientAuthenticator.h
+++ b/Swiften/SASL/ClientAuthenticator.h
@@ -7,10 +7,13 @@
#pragma once
#include <boost/optional.hpp>
-
#include <string>
#include <vector>
+#include <Swiften/Base/SafeString.h>
+#include <Swiften/Base/SafeByteArray.h>
+#include <Swiften/Base/ByteArray.h>
+
namespace Swift {
class ClientAuthenticator {
public:
@@ -21,14 +24,14 @@ namespace Swift {
return name;
}
- void setCredentials(const std::string& authcid, const std::string& password, const std::string& authzid = std::string()) {
+ void setCredentials(const std::string& authcid, const SafeString& password, const std::string& authzid = std::string()) {
this->authcid = authcid;
this->password = password;
this->authzid = authzid;
}
- virtual boost::optional< std::vector<unsigned char> > getResponse() const = 0;
- virtual bool setChallenge(const boost::optional< std::vector<unsigned char> >&) = 0;
+ virtual boost::optional<SafeByteArray> getResponse() const = 0;
+ virtual bool setChallenge(const boost::optional<ByteArray>&) = 0;
const std::string& getAuthenticationID() const {
return authcid;
@@ -38,14 +41,14 @@ namespace Swift {
return authzid;
}
- const std::string& getPassword() const {
+ const SafeString& getPassword() const {
return password;
}
private:
std::string name;
std::string authcid;
- std::string password;
+ SafeString password;
std::string authzid;
};
}
diff --git a/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp b/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp
index 3ff0893..ffa098c 100644
--- a/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp
+++ b/Swiften/SASL/DIGESTMD5ClientAuthenticator.cpp
@@ -18,9 +18,9 @@ namespace Swift {
DIGESTMD5ClientAuthenticator::DIGESTMD5ClientAuthenticator(const std::string& host, const std::string& nonce) : ClientAuthenticator("DIGEST-MD5"), step(Initial), host(host), cnonce(nonce) {
}
-boost::optional<ByteArray> DIGESTMD5ClientAuthenticator::getResponse() const {
+boost::optional<SafeByteArray> DIGESTMD5ClientAuthenticator::getResponse() const {
if (step == Initial) {
- return boost::optional<ByteArray>();
+ return boost::optional<SafeByteArray>();
}
else if (step == Response) {
std::string realm;
@@ -33,7 +33,9 @@ boost::optional<ByteArray> DIGESTMD5ClientAuthenticator::getResponse() const {
// Compute the response value
ByteArray A1 = concat(
- MD5::getHash(createByteArray(getAuthenticationID() + ":" + realm + ":" + getPassword())), createByteArray(":"), createByteArray(*challenge.getValue("nonce")), createByteArray(":"), createByteArray(cnonce));
+ MD5::getHash(
+ createSafeByteArray(concat(SafeString(getAuthenticationID().c_str()), SafeString(":"), SafeString(realm.c_str()), SafeString(":"), getPassword()))),
+ createByteArray(":"), createByteArray(*challenge.getValue("nonce")), createByteArray(":"), createByteArray(cnonce));
if (!getAuthorizationID().empty()) {
append(A1, createByteArray(":" + getAuthenticationID()));
}
@@ -60,10 +62,10 @@ boost::optional<ByteArray> DIGESTMD5ClientAuthenticator::getResponse() const {
if (!getAuthorizationID().empty()) {
response.setValue("authzid", getAuthorizationID());
}
- return response.serialize();
+ return createSafeByteArray(response.serialize());
}
else {
- return boost::optional<ByteArray>();
+ return boost::optional<SafeByteArray>();
}
}
diff --git a/Swiften/SASL/DIGESTMD5ClientAuthenticator.h b/Swiften/SASL/DIGESTMD5ClientAuthenticator.h
index 82c8bc5..55bd592 100644
--- a/Swiften/SASL/DIGESTMD5ClientAuthenticator.h
+++ b/Swiften/SASL/DIGESTMD5ClientAuthenticator.h
@@ -12,13 +12,14 @@
#include <vector>
#include <Swiften/SASL/ClientAuthenticator.h>
#include <Swiften/SASL/DIGESTMD5Properties.h>
+#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
class DIGESTMD5ClientAuthenticator : public ClientAuthenticator {
public:
DIGESTMD5ClientAuthenticator(const std::string& host, const std::string& nonce);
- virtual boost::optional<std::vector<unsigned char> > getResponse() const;
+ virtual boost::optional<SafeByteArray> getResponse() const;
virtual bool setChallenge(const boost::optional<std::vector<unsigned char> >&);
private:
diff --git a/Swiften/SASL/PLAINClientAuthenticator.cpp b/Swiften/SASL/PLAINClientAuthenticator.cpp
index 675542f..17f880a 100644
--- a/Swiften/SASL/PLAINClientAuthenticator.cpp
+++ b/Swiften/SASL/PLAINClientAuthenticator.cpp
@@ -12,8 +12,8 @@ namespace Swift {
PLAINClientAuthenticator::PLAINClientAuthenticator() : ClientAuthenticator("PLAIN") {
}
-boost::optional<ByteArray> PLAINClientAuthenticator::getResponse() const {
- return concat(createByteArray(getAuthorizationID()), createByteArray('\0'), createByteArray(getAuthenticationID()), createByteArray('\0'), createByteArray(getPassword()));
+boost::optional<SafeByteArray> PLAINClientAuthenticator::getResponse() const {
+ return concat(createSafeByteArray(getAuthorizationID()), createSafeByteArray('\0'), createSafeByteArray(getAuthenticationID()), createSafeByteArray('\0'), createSafeByteArray(getPassword()));
}
bool PLAINClientAuthenticator::setChallenge(const boost::optional<ByteArray>&) {
diff --git a/Swiften/SASL/PLAINClientAuthenticator.h b/Swiften/SASL/PLAINClientAuthenticator.h
index 4e8f8be..83e45c1 100644
--- a/Swiften/SASL/PLAINClientAuthenticator.h
+++ b/Swiften/SASL/PLAINClientAuthenticator.h
@@ -14,7 +14,7 @@ namespace Swift {
public:
PLAINClientAuthenticator();
- virtual boost::optional<ByteArray> getResponse() const;
+ virtual boost::optional<SafeByteArray> getResponse() const;
virtual bool setChallenge(const boost::optional<ByteArray>&);
};
}
diff --git a/Swiften/SASL/PLAINMessage.cpp b/Swiften/SASL/PLAINMessage.cpp
index 036887c..20ffea7 100644
--- a/Swiften/SASL/PLAINMessage.cpp
+++ b/Swiften/SASL/PLAINMessage.cpp
@@ -5,13 +5,14 @@
*/
#include <Swiften/SASL/PLAINMessage.h>
+#include <Swiften/Base/Concat.h>
namespace Swift {
-PLAINMessage::PLAINMessage(const std::string& authcid, const std::string& password, const std::string& authzid) : authcid(authcid), authzid(authzid), password(password) {
+PLAINMessage::PLAINMessage(const std::string& authcid, const SafeByteArray& password, const std::string& authzid) : authcid(authcid), authzid(authzid), password(password) {
}
-PLAINMessage::PLAINMessage(const ByteArray& value) {
+PLAINMessage::PLAINMessage(const SafeByteArray& value) {
size_t i = 0;
while (i < value.size() && value[i] != '\0') {
authzid += value[i];
@@ -31,14 +32,13 @@ PLAINMessage::PLAINMessage(const ByteArray& value) {
}
++i;
while (i < value.size()) {
- password += value[i];
+ password.push_back(value[i]);
++i;
}
}
-ByteArray PLAINMessage::getValue() const {
- std::string s = authzid + '\0' + authcid + '\0' + password;
- return createByteArray(s);
+SafeByteArray PLAINMessage::getValue() const {
+ return concat(createSafeByteArray(authzid), createSafeByteArray('\0'), createSafeByteArray(authcid), createSafeByteArray('\0'), password);
}
}
diff --git a/Swiften/SASL/PLAINMessage.h b/Swiften/SASL/PLAINMessage.h
index 916d267..46ee8f7 100644
--- a/Swiften/SASL/PLAINMessage.h
+++ b/Swiften/SASL/PLAINMessage.h
@@ -9,21 +9,21 @@
#pragma once
#include <string>
-#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
class PLAINMessage {
public:
- PLAINMessage(const std::string& authcid, const std::string& password, const std::string& authzid = "");
- PLAINMessage(const ByteArray& value);
+ PLAINMessage(const std::string& authcid, const SafeByteArray& password, const std::string& authzid = "");
+ PLAINMessage(const SafeByteArray& value);
- ByteArray getValue() const;
+ SafeByteArray getValue() const;
const std::string& getAuthenticationID() const {
return authcid;
}
- const std::string& getPassword() const {
+ const SafeByteArray& getPassword() const {
return password;
}
@@ -34,6 +34,6 @@ namespace Swift {
private:
std::string authcid;
std::string authzid;
- std::string password;
+ SafeByteArray password;
};
}
diff --git a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp
index bda35b9..a9855a5 100644
--- a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp
+++ b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp
@@ -39,23 +39,23 @@ static std::string escape(const std::string& s) {
SCRAMSHA1ClientAuthenticator::SCRAMSHA1ClientAuthenticator(const std::string& nonce, bool useChannelBinding) : ClientAuthenticator(useChannelBinding ? "SCRAM-SHA-1-PLUS" : "SCRAM-SHA-1"), step(Initial), clientnonce(nonce), useChannelBinding(useChannelBinding) {
}
-boost::optional<ByteArray> SCRAMSHA1ClientAuthenticator::getResponse() const {
+boost::optional<SafeByteArray> SCRAMSHA1ClientAuthenticator::getResponse() const {
if (step == Initial) {
- return concat(getGS2Header(), getInitialBareClientMessage());
+ return createSafeByteArray(concat(getGS2Header(), getInitialBareClientMessage()));
}
else if (step == Proof) {
ByteArray clientKey = HMACSHA1::getResult(saltedPassword, createByteArray("Client Key"));
ByteArray storedKey = SHA1::getHash(clientKey);
- ByteArray clientSignature = HMACSHA1::getResult(storedKey, authMessage);
+ ByteArray clientSignature = HMACSHA1::getResult(createSafeByteArray(storedKey), authMessage);
ByteArray clientProof = clientKey;
for (unsigned int i = 0; i < clientProof.size(); ++i) {
clientProof[i] ^= clientSignature[i];
}
ByteArray result = concat(getFinalMessageWithoutProof(), createByteArray(",p="), createByteArray(Base64::encode(clientProof)));
- return result;
+ return createSafeByteArray(result);
}
else {
- return boost::optional<ByteArray>();
+ return boost::optional<SafeByteArray>();
}
}
@@ -100,7 +100,7 @@ bool SCRAMSHA1ClientAuthenticator::setChallenge(const boost::optional<ByteArray>
}
// Compute all the values needed for the server signature
- saltedPassword = PBKDF2::encode(createByteArray(StringPrep::getPrepared(getPassword(), StringPrep::SASLPrep)), salt, iterations);
+ saltedPassword = PBKDF2::encode(createSafeByteArray(StringPrep::getPrepared(getPassword(), StringPrep::SASLPrep)), salt, iterations);
authMessage = concat(getInitialBareClientMessage(), createByteArray(","), initialServerMessage, createByteArray(","), getFinalMessageWithoutProof());
ByteArray serverKey = HMACSHA1::getResult(saltedPassword, createByteArray("Server Key"));
serverSignature = HMACSHA1::getResult(serverKey, authMessage);
diff --git a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h
index 5780bc4..d140013 100644
--- a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h
+++ b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h
@@ -20,7 +20,7 @@ namespace Swift {
void setTLSChannelBindingData(const ByteArray& channelBindingData);
- virtual boost::optional<ByteArray> getResponse() const;
+ virtual boost::optional<SafeByteArray> getResponse() const;
virtual bool setChallenge(const boost::optional<ByteArray>&);
private:
diff --git a/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp b/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp
index a16ffac..a16eda8 100644
--- a/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp
+++ b/Swiften/SASL/UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp
@@ -9,6 +9,7 @@
#include <Swiften/SASL/DIGESTMD5ClientAuthenticator.h>
#include <Swiften/Base/ByteArray.h>
+#include <QA/Checker/IO.h>
using namespace Swift;
@@ -36,9 +37,9 @@ class DIGESTMD5ClientAuthenticatorTest : public CppUnit::TestFixture {
"nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\","
"qop=auth,charset=utf-8,algorithm=md5-sess"));
- ByteArray response = *testling.getResponse();
+ SafeByteArray response = *testling.getResponse();
- CPPUNIT_ASSERT_EQUAL(std::string("charset=utf-8,cnonce=\"abcdefgh\",digest-uri=\"xmpp/xmpp.example.com\",nc=00000001,nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\",qop=auth,realm=\"example.com\",response=088891c800ecff1b842159ad6459104a,username=\"user\""), byteArrayToString(response));
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("charset=utf-8,cnonce=\"abcdefgh\",digest-uri=\"xmpp/xmpp.example.com\",nc=00000001,nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\",qop=auth,realm=\"example.com\",response=088891c800ecff1b842159ad6459104a,username=\"user\""), response);
}
void testGetResponse_WithAuthorizationID() {
@@ -50,9 +51,9 @@ class DIGESTMD5ClientAuthenticatorTest : public CppUnit::TestFixture {
"nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\","
"qop=auth,charset=utf-8,algorithm=md5-sess"));
- ByteArray response = *testling.getResponse();
+ SafeByteArray response = *testling.getResponse();
- CPPUNIT_ASSERT_EQUAL(std::string("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\""), byteArrayToString(response));
+ 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);
}
};
diff --git a/Swiften/SASL/UnitTest/PLAINClientAuthenticatorTest.cpp b/Swiften/SASL/UnitTest/PLAINClientAuthenticatorTest.cpp
index 5c35e79..d6c4188 100644
--- a/Swiften/SASL/UnitTest/PLAINClientAuthenticatorTest.cpp
+++ b/Swiften/SASL/UnitTest/PLAINClientAuthenticatorTest.cpp
@@ -24,7 +24,7 @@ class PLAINClientAuthenticatorTest : public CppUnit::TestFixture {
testling.setCredentials("user", "pass");
- CPPUNIT_ASSERT_EQUAL(*testling.getResponse(), createByteArray("\0user\0pass", 10));
+ CPPUNIT_ASSERT_EQUAL(*testling.getResponse(), createSafeByteArray("\0user\0pass", 10));
}
void testGetResponse_WithAuthzID() {
@@ -32,7 +32,7 @@ class PLAINClientAuthenticatorTest : public CppUnit::TestFixture {
testling.setCredentials("user", "pass", "authz");
- CPPUNIT_ASSERT_EQUAL(*testling.getResponse(), createByteArray("authz\0user\0pass", 15));
+ CPPUNIT_ASSERT_EQUAL(*testling.getResponse(), createSafeByteArray("authz\0user\0pass", 15));
}
};
diff --git a/Swiften/SASL/UnitTest/PLAINMessageTest.cpp b/Swiften/SASL/UnitTest/PLAINMessageTest.cpp
index dc3f82f..26331d6 100644
--- a/Swiften/SASL/UnitTest/PLAINMessageTest.cpp
+++ b/Swiften/SASL/UnitTest/PLAINMessageTest.cpp
@@ -29,39 +29,39 @@ class PLAINMessageTest : public CppUnit::TestFixture
PLAINMessageTest() {}
void testGetValue_WithoutAuthzID() {
- PLAINMessage message("user", "pass");
- CPPUNIT_ASSERT_EQUAL(message.getValue(), createByteArray("\0user\0pass", 10));
+ PLAINMessage message("user", createSafeByteArray("pass"));
+ CPPUNIT_ASSERT_EQUAL(message.getValue(), createSafeByteArray("\0user\0pass", 10));
}
void testGetValue_WithAuthzID() {
- PLAINMessage message("user", "pass", "authz");
- CPPUNIT_ASSERT_EQUAL(message.getValue(), createByteArray("authz\0user\0pass", 15));
+ PLAINMessage message("user", createSafeByteArray("pass"), "authz");
+ CPPUNIT_ASSERT_EQUAL(message.getValue(), createSafeByteArray("authz\0user\0pass", 15));
}
void testConstructor_WithoutAuthzID() {
- PLAINMessage message(createByteArray("\0user\0pass", 10));
+ PLAINMessage message(createSafeByteArray("\0user\0pass", 10));
CPPUNIT_ASSERT_EQUAL(std::string(""), message.getAuthorizationID());
CPPUNIT_ASSERT_EQUAL(std::string("user"), message.getAuthenticationID());
- CPPUNIT_ASSERT_EQUAL(std::string("pass"), message.getPassword());
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("pass"), message.getPassword());
}
void testConstructor_WithAuthzID() {
- PLAINMessage message(createByteArray("authz\0user\0pass", 15));
+ PLAINMessage message(createSafeByteArray("authz\0user\0pass", 15));
CPPUNIT_ASSERT_EQUAL(std::string("authz"), message.getAuthorizationID());
CPPUNIT_ASSERT_EQUAL(std::string("user"), message.getAuthenticationID());
- CPPUNIT_ASSERT_EQUAL(std::string("pass"), message.getPassword());
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("pass"), message.getPassword());
}
void testConstructor_NoAuthcid() {
- PLAINMessage message(createByteArray("authzid", 7));
+ PLAINMessage message(createSafeByteArray("authzid", 7));
CPPUNIT_ASSERT_EQUAL(std::string(""), message.getAuthenticationID());
}
void testConstructor_NoPassword() {
- PLAINMessage message(createByteArray("authzid\0authcid", 15));
+ PLAINMessage message(createSafeByteArray("authzid\0authcid", 15));
CPPUNIT_ASSERT_EQUAL(std::string(""), message.getAuthenticationID());
}
diff --git a/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp b/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp
index 78afaf7..0112691 100644
--- a/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp
+++ b/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp
@@ -9,6 +9,7 @@
#include <Swiften/SASL/SCRAMSHA1ClientAuthenticator.h>
#include <Swiften/Base/ByteArray.h>
+#include <QA/Checker/IO.h>
using namespace Swift;
@@ -43,36 +44,36 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {
SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH");
testling.setCredentials("user", "pass", "");
- ByteArray response = *testling.getResponse();
+ SafeByteArray response = *testling.getResponse();
- CPPUNIT_ASSERT_EQUAL(std::string("n,,n=user,r=abcdefghABCDEFGH"), byteArrayToString(response));
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("n,,n=user,r=abcdefghABCDEFGH"), response);
}
void testGetInitialResponse_UsernameHasSpecialChars() {
SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH");
testling.setCredentials(",us=,er=", "pass", "");
- ByteArray response = *testling.getResponse();
+ SafeByteArray response = *testling.getResponse();
- CPPUNIT_ASSERT_EQUAL(std::string("n,,n==2Cus=3D=2Cer=3D,r=abcdefghABCDEFGH"), byteArrayToString(response));
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("n,,n==2Cus=3D=2Cer=3D,r=abcdefghABCDEFGH"), response);
}
void testGetInitialResponse_WithAuthorizationID() {
SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH");
testling.setCredentials("user", "pass", "auth");
- ByteArray response = *testling.getResponse();
+ SafeByteArray response = *testling.getResponse();
- CPPUNIT_ASSERT_EQUAL(std::string("n,a=auth,n=user,r=abcdefghABCDEFGH"), byteArrayToString(response));
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("n,a=auth,n=user,r=abcdefghABCDEFGH"), response);
}
void testGetInitialResponse_WithAuthorizationIDWithSpecialChars() {
SCRAMSHA1ClientAuthenticator testling("abcdefghABCDEFGH");
testling.setCredentials("user", "pass", "a=u,th");
- ByteArray response = *testling.getResponse();
+ SafeByteArray response = *testling.getResponse();
- CPPUNIT_ASSERT_EQUAL(std::string("n,a=a=3Du=2Cth,n=user,r=abcdefghABCDEFGH"), byteArrayToString(response));
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("n,a=a=3Du=2Cth,n=user,r=abcdefghABCDEFGH"), response);
}
void testGetInitialResponse_WithoutChannelBindingWithTLSChannelBindingData() {
@@ -80,9 +81,9 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {
testling.setTLSChannelBindingData(createByteArray("xyza"));
testling.setCredentials("user", "pass", "");
- ByteArray response = *testling.getResponse();
+ SafeByteArray response = *testling.getResponse();
- CPPUNIT_ASSERT_EQUAL(std::string("y,,n=user,r=abcdefghABCDEFGH"), byteArrayToString(response));
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("y,,n=user,r=abcdefghABCDEFGH"), response);
}
void testGetInitialResponse_WithChannelBindingWithTLSChannelBindingData() {
@@ -90,9 +91,9 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {
testling.setTLSChannelBindingData(createByteArray("xyza"));
testling.setCredentials("user", "pass", "");
- ByteArray response = *testling.getResponse();
+ SafeByteArray response = *testling.getResponse();
- CPPUNIT_ASSERT_EQUAL(std::string("p=tls-unique,,n=user,r=abcdefghABCDEFGH"), byteArrayToString(response));
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("p=tls-unique,,n=user,r=abcdefghABCDEFGH"), response);
}
void testGetFinalResponse() {
@@ -100,9 +101,9 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {
testling.setCredentials("user", "pass", "");
testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096"));
- ByteArray response = *testling.getResponse();
+ SafeByteArray response = *testling.getResponse();
- CPPUNIT_ASSERT_EQUAL(std::string("c=biws,r=abcdefghABCDEFGH,p=CZbjGDpIteIJwQNBgO0P8pKkMGY="), byteArrayToString(response));
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("c=biws,r=abcdefghABCDEFGH,p=CZbjGDpIteIJwQNBgO0P8pKkMGY="), response);
}
void testGetFinalResponse_WithoutChannelBindingWithTLSChannelBindingData() {
@@ -111,9 +112,9 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {
testling.setTLSChannelBindingData(createByteArray("xyza"));
testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096"));
- ByteArray response = *testling.getResponse();
+ SafeByteArray response = *testling.getResponse();
- CPPUNIT_ASSERT_EQUAL(std::string("c=eSws,r=abcdefghABCDEFGH,p=JNpsiFEcxZvNZ1+FFBBqrYvYxMk="), byteArrayToString(response));
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("c=eSws,r=abcdefghABCDEFGH,p=JNpsiFEcxZvNZ1+FFBBqrYvYxMk="), response);
}
void testGetFinalResponse_WithChannelBindingWithTLSChannelBindingData() {
@@ -122,9 +123,9 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {
testling.setTLSChannelBindingData(createByteArray("xyza"));
testling.setChallenge(createByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096"));
- ByteArray response = *testling.getResponse();
+ SafeByteArray response = *testling.getResponse();
- CPPUNIT_ASSERT_EQUAL(std::string("c=cD10bHMtdW5pcXVlLCx4eXph,r=abcdefghABCDEFGH,p=i6Rghite81P1ype8XxaVAa5l7v0="), byteArrayToString(response));
+ CPPUNIT_ASSERT_EQUAL(createSafeByteArray("c=cD10bHMtdW5pcXVlLCx4eXph,r=abcdefghABCDEFGH,p=i6Rghite81P1ype8XxaVAa5l7v0="), response);
}
void testSetFinalChallenge() {
diff --git a/Swiften/Serializer/AuthRequestSerializer.cpp b/Swiften/Serializer/AuthRequestSerializer.cpp
index 415a0ff..33bdd77 100644
--- a/Swiften/Serializer/AuthRequestSerializer.cpp
+++ b/Swiften/Serializer/AuthRequestSerializer.cpp
@@ -9,6 +9,7 @@
#include <Swiften/Elements/AuthRequest.h>
#include <Swiften/StringCodecs/Base64.h>
#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/SafeString.h>
namespace Swift {
@@ -17,17 +18,17 @@ AuthRequestSerializer::AuthRequestSerializer() {
std::string AuthRequestSerializer::serialize(boost::shared_ptr<Element> element) const {
boost::shared_ptr<AuthRequest> authRequest(boost::dynamic_pointer_cast<AuthRequest>(element));
- std::string value;
- boost::optional<std::vector<unsigned char> > message = authRequest->getMessage();
+ SafeString value;
+ boost::optional<SafeByteArray> message = authRequest->getMessage();
if (message) {
if ((*message).empty()) {
value = "=";
}
else {
- value = Base64::encode(ByteArray(*message));
+ value = Base64::encode(*message);
}
}
- return "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"" + authRequest->getMechanism() + "\">" + value + "</auth>";
+ return "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"" + authRequest->getMechanism() + "\">" + value.toString() + "</auth>";
}
}
diff --git a/Swiften/Serializer/AuthResponseSerializer.cpp b/Swiften/Serializer/AuthResponseSerializer.cpp
index 0d1872b..cfdcc99 100644
--- a/Swiften/Serializer/AuthResponseSerializer.cpp
+++ b/Swiften/Serializer/AuthResponseSerializer.cpp
@@ -9,6 +9,7 @@
#include <Swiften/Elements/AuthResponse.h>
#include <Swiften/StringCodecs/Base64.h>
#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/SafeString.h>
namespace Swift {
@@ -17,17 +18,17 @@ AuthResponseSerializer::AuthResponseSerializer() {
std::string AuthResponseSerializer::serialize(boost::shared_ptr<Element> element) const {
boost::shared_ptr<AuthResponse> authResponse(boost::dynamic_pointer_cast<AuthResponse>(element));
- std::string value;
- boost::optional<std::vector<unsigned char> > message = authResponse->getValue();
+ SafeString value;
+ boost::optional<SafeByteArray> message = authResponse->getValue();
if (message) {
if ((*message).empty()) {
value = "=";
}
else {
- value = Base64::encode(ByteArray(*message));
+ value = Base64::encode(*message);
}
}
- return "<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" + value + "</response>";
+ return "<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" + value.toString() + "</response>";
}
}
diff --git a/Swiften/Serializer/UnitTest/AuthRequestSerializerTest.cpp b/Swiften/Serializer/UnitTest/AuthRequestSerializerTest.cpp
index 8270139..d5c0a09 100644
--- a/Swiften/Serializer/UnitTest/AuthRequestSerializerTest.cpp
+++ b/Swiften/Serializer/UnitTest/AuthRequestSerializerTest.cpp
@@ -24,7 +24,7 @@ class AuthRequestSerializerTest : public CppUnit::TestFixture {
void testSerialize() {
AuthRequestSerializer testling;
boost::shared_ptr<AuthRequest> authRequest(new AuthRequest("PLAIN"));
- authRequest->setMessage(createByteArray("foo"));
+ authRequest->setMessage(createSafeByteArray("foo"));
CPPUNIT_ASSERT_EQUAL(std::string(
"<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"PLAIN\">"
@@ -44,7 +44,7 @@ class AuthRequestSerializerTest : public CppUnit::TestFixture {
void testSerialize_EmptyMessage() {
AuthRequestSerializer testling;
boost::shared_ptr<AuthRequest> authRequest(new AuthRequest("PLAIN"));
- authRequest->setMessage(std::vector<unsigned char>());
+ authRequest->setMessage(SafeByteArray());
CPPUNIT_ASSERT_EQUAL(std::string(
"<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"PLAIN\">"
diff --git a/Swiften/Serializer/UnitTest/AuthResponseSerializerTest.cpp b/Swiften/Serializer/UnitTest/AuthResponseSerializerTest.cpp
index e790cc3..8887b27 100644
--- a/Swiften/Serializer/UnitTest/AuthResponseSerializerTest.cpp
+++ b/Swiften/Serializer/UnitTest/AuthResponseSerializerTest.cpp
@@ -24,7 +24,7 @@ class AuthResponseSerializerTest : public CppUnit::TestFixture {
void testSerialize() {
AuthResponseSerializer testling;
boost::shared_ptr<AuthResponse> authResponse(new AuthResponse());
- authResponse->setValue(createByteArray("foo"));
+ authResponse->setValue(createSafeByteArray("foo"));
CPPUNIT_ASSERT_EQUAL(std::string(
"<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"
@@ -44,7 +44,7 @@ class AuthResponseSerializerTest : public CppUnit::TestFixture {
void testSerialize_EmptyMessage() {
AuthResponseSerializer testling;
boost::shared_ptr<AuthResponse> authResponse(new AuthResponse());
- authResponse->setValue(std::vector<unsigned char>());
+ authResponse->setValue(SafeByteArray());
CPPUNIT_ASSERT_EQUAL(std::string(
"<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"
diff --git a/Swiften/Server/ServerFromClientSession.cpp b/Swiften/Server/ServerFromClientSession.cpp
index b047f69..dbe9745 100644
--- a/Swiften/Server/ServerFromClientSession.cpp
+++ b/Swiften/Server/ServerFromClientSession.cpp
@@ -51,7 +51,7 @@ void ServerFromClientSession::handleElement(boost::shared_ptr<Element> element)
getXMPPLayer()->resetParser();
}
else {
- PLAINMessage plainMessage(authRequest->getMessage() ? *authRequest->getMessage() : createByteArray(""));
+ PLAINMessage plainMessage(authRequest->getMessage() ? *authRequest->getMessage() : createSafeByteArray(""));
if (userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), plainMessage.getPassword())) {
getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
user_ = plainMessage.getAuthenticationID();
diff --git a/Swiften/Server/SimpleUserRegistry.cpp b/Swiften/Server/SimpleUserRegistry.cpp
index 9930a39..a519ac2 100644
--- a/Swiften/Server/SimpleUserRegistry.cpp
+++ b/Swiften/Server/SimpleUserRegistry.cpp
@@ -11,13 +11,13 @@ namespace Swift {
SimpleUserRegistry::SimpleUserRegistry() {
}
-bool SimpleUserRegistry::isValidUserPassword(const JID& user, const std::string& password) const {
- std::map<JID,std::string>::const_iterator i = users.find(user);
+bool SimpleUserRegistry::isValidUserPassword(const JID& user, const SafeByteArray& password) const {
+ std::map<JID,SafeByteArray>::const_iterator i = users.find(user);
return i != users.end() ? i->second == password : false;
}
void SimpleUserRegistry::addUser(const JID& user, const std::string& password) {
- users.insert(std::make_pair(user, password));
+ users.insert(std::make_pair(user, createSafeByteArray(password)));
}
}
diff --git a/Swiften/Server/SimpleUserRegistry.h b/Swiften/Server/SimpleUserRegistry.h
index ad1791b..324c099 100644
--- a/Swiften/Server/SimpleUserRegistry.h
+++ b/Swiften/Server/SimpleUserRegistry.h
@@ -19,10 +19,10 @@ namespace Swift {
public:
SimpleUserRegistry();
- virtual bool isValidUserPassword(const JID& user, const std::string& password) const;
+ virtual bool isValidUserPassword(const JID& user, const SafeByteArray& password) const;
void addUser(const JID& user, const std::string& password);
private:
- std::map<JID, std::string> users;
+ std::map<JID, SafeByteArray> users;
};
}
diff --git a/Swiften/Server/UserRegistry.h b/Swiften/Server/UserRegistry.h
index c021fc4..9584a7e 100644
--- a/Swiften/Server/UserRegistry.h
+++ b/Swiften/Server/UserRegistry.h
@@ -7,15 +7,15 @@
#pragma once
#include <string>
+#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
-
class JID;
class UserRegistry {
public:
virtual ~UserRegistry();
- virtual bool isValidUserPassword(const JID& user, const std::string& password) const = 0;
+ virtual bool isValidUserPassword(const JID& user, const SafeByteArray& password) const = 0;
};
}
diff --git a/Swiften/StringCodecs/Base64.cpp b/Swiften/StringCodecs/Base64.cpp
index 4ec2e16..d8511b4 100644
--- a/Swiften/StringCodecs/Base64.cpp
+++ b/Swiften/StringCodecs/Base64.cpp
@@ -10,42 +10,54 @@
#include <Swiften/StringCodecs/Base64.h>
#include <Swiften/Base/Algorithm.h>
+#include <Swiften/Base/SafeString.h>
namespace Swift {
#pragma GCC diagnostic ignored "-Wold-style-cast"
-std::string Base64::encode(const ByteArray &s) {
- int i;
- int len = s.size();
- char tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
- int a, b, c;
-
- std::string p;
- p.resize((len+2)/3*4);
- int at = 0;
- for( i = 0; i < len; i += 3 ) {
- a = ((unsigned char) (s[i]) & 3) << 4;
- if(i + 1 < len) {
- a += (unsigned char) (s[i + 1]) >> 4;
- b = ((unsigned char) (s[i + 1]) & 0xF) << 2;
- if(i + 2 < len) {
- b += (unsigned char) (s[i + 2]) >> 6;
- c = (unsigned char) (s[i + 2]) & 0x3F;
+namespace {
+ template<typename TargetType, typename SourceType>
+ TargetType base64Encode(const SourceType& s) {
+ int i;
+ int len = s.size();
+ char tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+ int a, b, c;
+
+ TargetType p;
+ p.resize((len+2)/3*4);
+ int at = 0;
+ for( i = 0; i < len; i += 3 ) {
+ a = ((unsigned char) (s[i]) & 3) << 4;
+ if(i + 1 < len) {
+ a += (unsigned char) (s[i + 1]) >> 4;
+ b = ((unsigned char) (s[i + 1]) & 0xF) << 2;
+ if(i + 2 < len) {
+ b += (unsigned char) (s[i + 2]) >> 6;
+ c = (unsigned char) (s[i + 2]) & 0x3F;
+ }
+ else
+ c = 64;
+ }
+ else {
+ b = c = 64;
}
- else
- c = 64;
- }
- else {
- b = c = 64;
- }
- p[at++] = tbl[(unsigned char) (s[i]) >> 2];
- p[at++] = tbl[a];
- p[at++] = tbl[b];
- p[at++] = tbl[c];
+ p[at++] = tbl[(unsigned char) (s[i]) >> 2];
+ p[at++] = tbl[a];
+ p[at++] = tbl[b];
+ p[at++] = tbl[c];
+ }
+ return p;
}
- return p;
+}
+
+std::string Base64::encode(const ByteArray &s) {
+ return base64Encode<std::string, ByteArray>(s);
+}
+
+SafeString Base64::encode(const SafeByteArray &s) {
+ return base64Encode<SafeString, SafeByteArray>(s);
}
ByteArray Base64::decode(const std::string& input) {
diff --git a/Swiften/StringCodecs/Base64.h b/Swiften/StringCodecs/Base64.h
index 3b14595..00a290d 100644
--- a/Swiften/StringCodecs/Base64.h
+++ b/Swiften/StringCodecs/Base64.h
@@ -10,11 +10,14 @@
#include <string>
#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
class Base64 {
public:
static std::string encode(const ByteArray& s);
+ static SafeString encode(const SafeByteArray& s);
+
static ByteArray decode(const std::string &s);
};
}
diff --git a/Swiften/StringCodecs/HMACSHA1.cpp b/Swiften/StringCodecs/HMACSHA1.cpp
index e583e3b..fd951ae 100644
--- a/Swiften/StringCodecs/HMACSHA1.cpp
+++ b/Swiften/StringCodecs/HMACSHA1.cpp
@@ -9,37 +9,51 @@
#include <cassert>
#include <Swiften/StringCodecs/SHA1.h>
-#include <Swiften/Base/ByteArray.h>
#include <Swiften/Base/Algorithm.h>
-namespace Swift {
+using namespace Swift;
-static const unsigned int B = 64;
+namespace {
+ static const unsigned int B = 64;
-ByteArray HMACSHA1::getResult(const ByteArray& key, const ByteArray& data) {
- assert(key.size() <= B);
+ template<typename SourceType>
+ ByteArray getHMACSHA1(const SourceType& key, const ByteArray& data) {
+ assert(key.size() <= B);
- // Create the padded key
- ByteArray paddedKey(key);
- paddedKey.resize(B, 0x0);
+ // Create the padded key
+ SourceType paddedKey(key);
+ paddedKey.resize(B, 0x0);
- // Create the first value
- ByteArray x(paddedKey);
- for (unsigned int i = 0; i < x.size(); ++i) {
- x[i] ^= 0x36;
- }
- append(x, data);
+ // Create the first value
+ SourceType x(paddedKey);
+ for (unsigned int i = 0; i < x.size(); ++i) {
+ x[i] ^= 0x36;
+ }
+ append(x, data);
- // Create the second value
- ByteArray y(paddedKey);
- for (unsigned int i = 0; i < y.size(); ++i) {
- y[i] ^= 0x5c;
+ // Create the second value
+ SourceType y(paddedKey);
+ for (unsigned int i = 0; i < y.size(); ++i) {
+ y[i] ^= 0x5c;
+ }
+ append(y, SHA1::getHash(x));
+
+ return SHA1::getHash(y);
}
- append(y, SHA1::getHash(x));
+}
- return SHA1::getHash(y);
+namespace Swift {
+
+ByteArray HMACSHA1::getResult(const SafeByteArray& key, const ByteArray& data) {
+ return getHMACSHA1(key, data);
+}
+
+ByteArray HMACSHA1::getResult(const ByteArray& key, const ByteArray& data) {
+ return getHMACSHA1(key, data);
}
+
+
#if 0
// A tweaked version of HMACSHA1 that is more than twice as fast as the one above.
diff --git a/Swiften/StringCodecs/HMACSHA1.h b/Swiften/StringCodecs/HMACSHA1.h
index 39c6e4e..0463e64 100644
--- a/Swiften/StringCodecs/HMACSHA1.h
+++ b/Swiften/StringCodecs/HMACSHA1.h
@@ -7,10 +7,12 @@
#pragma once
#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
class HMACSHA1 {
public:
+ static ByteArray getResult(const SafeByteArray& key, const ByteArray& data);
static ByteArray getResult(const ByteArray& key, const ByteArray& data);
};
}
diff --git a/Swiften/StringCodecs/MD5.cpp b/Swiften/StringCodecs/MD5.cpp
index 9e69172..159eb87 100644
--- a/Swiften/StringCodecs/MD5.cpp
+++ b/Swiften/StringCodecs/MD5.cpp
@@ -351,16 +351,27 @@ md5_finish(md5_state_t *pms, md5_byte_t digest[16])
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}
-ByteArray MD5::getHash(const ByteArray& data) {
- ByteArray digest;
- digest.resize(16);
+namespace {
+ template<typename SourceType>
+ ByteArray getMD5Hash(const SourceType& data) {
+ ByteArray digest;
+ digest.resize(16);
+
+ md5_state_t state;
+ md5_init(&state);
+ md5_append(&state, reinterpret_cast<const md5_byte_t*>(vecptr(data)), data.size());
+ md5_finish(&state, reinterpret_cast<md5_byte_t*>(vecptr(digest)));
+
+ return digest;
+ }
+}
- md5_state_t state;
- md5_init(&state);
- md5_append(&state, reinterpret_cast<const md5_byte_t*>(vecptr(data)), data.size());
- md5_finish(&state, reinterpret_cast<md5_byte_t*>(vecptr(digest)));
+ByteArray MD5::getHash(const ByteArray& data) {
+ return getMD5Hash(data);
+}
- return digest;
+ByteArray MD5::getHash(const SafeByteArray& data) {
+ return getMD5Hash(data);
}
}
diff --git a/Swiften/StringCodecs/MD5.h b/Swiften/StringCodecs/MD5.h
index 93c48e9..b1d610c 100644
--- a/Swiften/StringCodecs/MD5.h
+++ b/Swiften/StringCodecs/MD5.h
@@ -7,10 +7,12 @@
#pragma once
#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
class MD5 {
public:
static ByteArray getHash(const ByteArray& data);
+ static ByteArray getHash(const SafeByteArray& data);
};
}
diff --git a/Swiften/StringCodecs/PBKDF2.cpp b/Swiften/StringCodecs/PBKDF2.cpp
index c4a5a7f..81e1208 100644
--- a/Swiften/StringCodecs/PBKDF2.cpp
+++ b/Swiften/StringCodecs/PBKDF2.cpp
@@ -10,7 +10,7 @@
namespace Swift {
-ByteArray PBKDF2::encode(const ByteArray& password, const ByteArray& salt, int iterations) {
+ByteArray PBKDF2::encode(const SafeByteArray& password, const ByteArray& salt, int iterations) {
ByteArray u = HMACSHA1::getResult(password, concat(salt, createByteArray("\0\0\0\1", 4)));
ByteArray result(u);
int i = 1;
diff --git a/Swiften/StringCodecs/PBKDF2.h b/Swiften/StringCodecs/PBKDF2.h
index dd31921..b1a5986 100644
--- a/Swiften/StringCodecs/PBKDF2.h
+++ b/Swiften/StringCodecs/PBKDF2.h
@@ -6,11 +6,11 @@
#pragma once
-#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
class PBKDF2 {
public:
- static ByteArray encode(const ByteArray& password, const ByteArray& salt, int iterations);
+ static ByteArray encode(const SafeByteArray& password, const ByteArray& salt, int iterations);
};
}
diff --git a/Swiften/StringCodecs/SHA1.cpp b/Swiften/StringCodecs/SHA1.cpp
index 5001fb2..e4081f4 100644
--- a/Swiften/StringCodecs/SHA1.cpp
+++ b/Swiften/StringCodecs/SHA1.cpp
@@ -197,11 +197,12 @@ std::vector<unsigned char> SHA1::getHash() const {
return digest;
}
-ByteArray SHA1::getHash(const ByteArray& input) {
+template<typename Container>
+ByteArray SHA1::getHashInternal(const Container& input) {
CTX context;
Init(&context);
- std::vector<unsigned char> inputCopy(input);
+ Container inputCopy(input);
Update(&context, (boost::uint8_t*) vecptr(inputCopy), inputCopy.size());
ByteArray digest;
@@ -211,4 +212,13 @@ ByteArray SHA1::getHash(const ByteArray& input) {
return digest;
}
+ByteArray SHA1::getHash(const ByteArray& input) {
+ return getHashInternal(input);
+}
+
+ByteArray SHA1::getHash(const SafeByteArray& input) {
+ return getHashInternal(input);
+}
+
+
}
diff --git a/Swiften/StringCodecs/SHA1.h b/Swiften/StringCodecs/SHA1.h
index 671d890..25bfa54 100644
--- a/Swiften/StringCodecs/SHA1.h
+++ b/Swiften/StringCodecs/SHA1.h
@@ -10,6 +10,7 @@
#include <boost/cstdint.hpp>
#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
class SHA1 {
@@ -26,6 +27,8 @@ namespace Swift {
*/
static ByteArray getHash(const ByteArray& data);
+ static ByteArray getHash(const SafeByteArray& data);
+
private:
typedef struct {
boost::uint32_t state[5];
@@ -37,6 +40,8 @@ namespace Swift {
static void Update(CTX* context, boost::uint8_t* data, unsigned int len);
static void Final(boost::uint8_t digest[20], CTX* context);
+ template<typename Container> static ByteArray getHashInternal(const Container& input);
+
private:
CTX context;
};
diff --git a/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp b/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp
index efb613f..1c9d158 100644
--- a/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp
+++ b/Swiften/StringCodecs/UnitTest/HMACSHA1Test.cpp
@@ -22,7 +22,7 @@ class HMACSHA1Test : public CppUnit::TestFixture {
public:
void testGetResult() {
- ByteArray result(HMACSHA1::getResult(createByteArray("foo"), createByteArray("foobar")));
+ ByteArray result(HMACSHA1::getResult(createSafeByteArray("foo"), createByteArray("foobar")));
CPPUNIT_ASSERT_EQUAL(createByteArray("\xa4\xee\xba\x8e\x63\x3d\x77\x88\x69\xf5\x68\xd0\x5a\x1b\x3d\xc7\x2b\xfd\x4\xdd"), result);
}
};
diff --git a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp
index ae55ac8..9d91fea 100644
--- a/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp
+++ b/Swiften/StringCodecs/UnitTest/PBKDF2Test.cpp
@@ -24,19 +24,19 @@ class PBKDF2Test : public CppUnit::TestFixture {
public:
void testGetResult_I1() {
- ByteArray result(PBKDF2::encode(createByteArray("password"), createByteArray("salt"), 1));
+ ByteArray result(PBKDF2::encode(createSafeByteArray("password"), createByteArray("salt"), 1));
CPPUNIT_ASSERT_EQUAL(createByteArray("\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6"), result);
}
void testGetResult_I2() {
- ByteArray result(PBKDF2::encode(createByteArray("password"), createByteArray("salt"), 2));
+ ByteArray result(PBKDF2::encode(createSafeByteArray("password"), createByteArray("salt"), 2));
CPPUNIT_ASSERT_EQUAL(createByteArray("\xea\x6c\x1\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57"), result);
}
void testGetResult_I4096() {
- ByteArray result(PBKDF2::encode(createByteArray("password"), createByteArray("salt"), 4096));
+ ByteArray result(PBKDF2::encode(createSafeByteArray("password"), createByteArray("salt"), 4096));
CPPUNIT_ASSERT_EQUAL(createByteArray("\x4b\x00\x79\x1\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1", 20), result);
}