summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/SASL')
-rw-r--r--Swiften/SASL/ClientAuthenticator.h2
-rw-r--r--Swiften/SASL/PLAINClientAuthenticator.cpp2
-rw-r--r--Swiften/SASL/PLAINClientAuthenticator.h2
-rw-r--r--Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp20
-rw-r--r--Swiften/SASL/SCRAMSHA1ClientAuthenticator.h6
-rw-r--r--Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp20
6 files changed, 37 insertions, 15 deletions
diff --git a/Swiften/SASL/ClientAuthenticator.h b/Swiften/SASL/ClientAuthenticator.h
index f93f44e..f42a51e 100644
--- a/Swiften/SASL/ClientAuthenticator.h
+++ b/Swiften/SASL/ClientAuthenticator.h
@@ -19,7 +19,7 @@ namespace Swift {
this->authzid = authzid;
}
- virtual ByteArray getResponse() = 0;
+ virtual ByteArray getResponse() const = 0;
virtual bool setChallenge(const ByteArray&) = 0;
const String& getAuthenticationID() const {
diff --git a/Swiften/SASL/PLAINClientAuthenticator.cpp b/Swiften/SASL/PLAINClientAuthenticator.cpp
index f61f1a0..8f88c3c 100644
--- a/Swiften/SASL/PLAINClientAuthenticator.cpp
+++ b/Swiften/SASL/PLAINClientAuthenticator.cpp
@@ -5,7 +5,7 @@ namespace Swift {
PLAINClientAuthenticator::PLAINClientAuthenticator() : ClientAuthenticator("PLAIN") {
}
-ByteArray PLAINClientAuthenticator::getResponse() {
+ByteArray PLAINClientAuthenticator::getResponse() const {
return ByteArray(getAuthorizationID()) + '\0' + ByteArray(getAuthenticationID()) + '\0' + ByteArray(getPassword());
}
diff --git a/Swiften/SASL/PLAINClientAuthenticator.h b/Swiften/SASL/PLAINClientAuthenticator.h
index bb24af7..854eb30 100644
--- a/Swiften/SASL/PLAINClientAuthenticator.h
+++ b/Swiften/SASL/PLAINClientAuthenticator.h
@@ -7,7 +7,7 @@ namespace Swift {
public:
PLAINClientAuthenticator();
- virtual ByteArray getResponse();
+ virtual ByteArray getResponse() const;
virtual bool setChallenge(const ByteArray&);
};
}
diff --git a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp
index b0a9f96..16c938a 100644
--- a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp
+++ b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp
@@ -17,19 +17,14 @@ SCRAMSHA1ClientAuthenticator::SCRAMSHA1ClientAuthenticator(const String& nonce)
// TODO: Normalize getPassword()
}
-ByteArray SCRAMSHA1ClientAuthenticator::getResponse() {
+ByteArray SCRAMSHA1ClientAuthenticator::getResponse() const {
if (step == Initial) {
return "n,," + getInitialBareClientMessage();
}
else {
- ByteArray saltedPassword = PBKDF2::encode(getPassword(), salt, iterations);
ByteArray clientKey = HMACSHA1::getResult(saltedPassword, "Client Key");
ByteArray storedKey = SHA1::getBinaryHash(clientKey);
- ByteArray serverKey = HMACSHA1::getResult(saltedPassword, "Server Key");
-
- ByteArray authMessage = getInitialBareClientMessage() + "," + initialServerMessage + "," + "c=biwsCg==," + "r=" + clientnonce + serverNonce;
ByteArray clientSignature = HMACSHA1::getResult(storedKey, authMessage);
- serverSignature = HMACSHA1::getResult(serverKey, authMessage);
ByteArray clientProof = clientKey;
for (unsigned int i = 0; i < clientProof.getSize(); ++i) {
clientProof[i] ^= clientSignature[i];
@@ -45,16 +40,23 @@ bool SCRAMSHA1ClientAuthenticator::setChallenge(const ByteArray& challenge) {
// TODO: Check if these values are correct
std::map<char, String> keys = parseMap(String(initialServerMessage.getData(), initialServerMessage.getSize()));
- salt = Base64::decode(keys['s']);
+ ByteArray salt = Base64::decode(keys['s']);
String clientServerNonce = keys['r'];
serverNonce = clientServerNonce.getSubstring(clientnonce.getUTF8Size(), clientServerNonce.npos());
- iterations = boost::lexical_cast<int>(keys['i'].getUTF8String());
+ int iterations = boost::lexical_cast<int>(keys['i'].getUTF8String());
+
+ // Compute all the values needed for the server signature
+ saltedPassword = PBKDF2::encode(StringPrep::getPrepared(getPassword(), StringPrep::SASLPrep), salt, iterations);
+ authMessage = getInitialBareClientMessage() + "," + initialServerMessage + "," + "c=biwsCg==," + "r=" + clientnonce + serverNonce;
+ ByteArray serverKey = HMACSHA1::getResult(saltedPassword, "Server Key");
+ serverSignature = HMACSHA1::getResult(serverKey, authMessage);
step = Proof;
return true;
}
else {
- return challenge == Base64::encode(ByteArray("v=") + Base64::encode(serverSignature));
+ ByteArray result = ByteArray("v=") + ByteArray(Base64::encode(serverSignature));
+ return challenge == result;
}
}
diff --git a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h
index 9504b35..108ac2e 100644
--- a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h
+++ b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.h
@@ -11,7 +11,7 @@ namespace Swift {
public:
SCRAMSHA1ClientAuthenticator(const String& nonce);
- virtual ByteArray getResponse();
+ virtual ByteArray getResponse() const;
virtual bool setChallenge(const ByteArray&);
private:
@@ -25,9 +25,9 @@ namespace Swift {
} step;
String clientnonce;
ByteArray initialServerMessage;
- int iterations;
ByteArray serverNonce;
- ByteArray salt;
+ ByteArray authMessage;
+ ByteArray saltedPassword;
ByteArray serverSignature;
};
}
diff --git a/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp b/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp
index 9f18ff0..618a748 100644
--- a/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp
+++ b/Swiften/SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp
@@ -11,6 +11,8 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testGetInitialResponse);
CPPUNIT_TEST(testGetInitialResponse_UsernameHasSpecialChars);
CPPUNIT_TEST(testGetFinalResponse);
+ CPPUNIT_TEST(testSetFinalChallenge);
+ CPPUNIT_TEST(testSetFinalChallenge_InvalidChallenge);
CPPUNIT_TEST_SUITE_END();
public:
@@ -44,6 +46,24 @@ class SCRAMSHA1ClientAuthenticatorTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(String("c=biwsCg==,r=abcdefghABCDEFGH,p=bVzb1EAf2hXw5Z+QIMYPTy5TOsU="), testling.getResponse().toString());
}
+
+ void testSetFinalChallenge() {
+ SCRAMSHA1ClientAuthenticator testling("abcdefgh");
+ testling.setCredentials("user", "pass", "");
+ testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096"));
+ bool result = testling.setChallenge(ByteArray("v=xWI/+vT8aAm0hKpqKIqctIDwtQE="));
+
+ CPPUNIT_ASSERT(result);
+ }
+
+ void testSetFinalChallenge_InvalidChallenge() {
+ SCRAMSHA1ClientAuthenticator testling("abcdefgh");
+ testling.setCredentials("user", "pass", "");
+ testling.setChallenge(ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096"));
+ bool result = testling.setChallenge(ByteArray("v=e26kI69ICb6zosapLLxrER/631A="));
+
+ CPPUNIT_ASSERT(!result);
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(SCRAMSHA1ClientAuthenticatorTest);