diff options
Diffstat (limited to 'Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp')
| -rw-r--r-- | Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp | 56 | 
1 files changed, 56 insertions, 0 deletions
diff --git a/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp new file mode 100644 index 0000000..b2e85e9 --- /dev/null +++ b/Swiften/SASL/SCRAMSHA1ClientAuthenticator.cpp @@ -0,0 +1,56 @@ +#include "Swiften/SASL/SCRAMSHA1ClientAuthenticator.h" + +#include <cassert> + +#include "Swiften/StringCodecs/SHA1.h" +#include "Swiften/StringCodecs/HMACSHA1.h" + +namespace Swift { + +SCRAMSHA1ClientAuthenticator::SCRAMSHA1ClientAuthenticator(const String& authcid, const String& password, const String& authzid, const ByteArray& nonce) : step(Initial), authcid(authcid), password(password), authzid(authzid), clientnonce(nonce) { +} + +ByteArray SCRAMSHA1ClientAuthenticator::getMessage() const { +	if (step == Initial) { +		return getInitialClientMessage(); +	} +	else { +		ByteArray mask = HMACSHA1::getResult(getClientVerifier(), initialServerMessage + getInitialClientMessage()); +		ByteArray p = SHA1::getBinaryHash(password); +		for (unsigned int i = 0; i < p.getSize(); ++i) { +			p[i] ^= mask[i]; +		} +		return p; +	} +} + +bool SCRAMSHA1ClientAuthenticator::setResponse(const ByteArray& response) { +	if (step == Initial) { +		initialServerMessage = response; +		step = Proof; +		return getSalt().getSize() > 0; +	} +	else { +		return response == HMACSHA1::getResult(getClientVerifier(), getInitialClientMessage() + initialServerMessage); +	} +} + +ByteArray SCRAMSHA1ClientAuthenticator::getSalt() const { +	if (initialServerMessage.getSize() < 8) { +		std::cerr << "ERROR: SCRAM-SHA1: Invalid server response" << std::endl; +		return ByteArray(); +	} +	else { +		return ByteArray(initialServerMessage.getData(), 8); +	} +} + +ByteArray SCRAMSHA1ClientAuthenticator::getClientVerifier() const { +	return HMACSHA1::getResult(SHA1::getBinaryHash(password), getSalt()); +} + +ByteArray SCRAMSHA1ClientAuthenticator::getInitialClientMessage() const { +	return ByteArray(authzid) + '\0' + ByteArray(authcid) + '\0' + ByteArray(clientnonce); +} + +}  | 
 Swift