Diff

util/sasl/scram.lua @ 3104:32150b4a8603

util.sasl.scram: Providing an API function to generate a salted password for the SCRAM-SHA-1 mechanism.
author Tobias Markmann <tm@ayena.de>
date Sat, 22 May 2010 19:04:53 +0200
parent 3103:87cf90ca8923
child 3106:f4341cac3ae1
line wrap: on
line diff
--- a/util/sasl/scram.lua	Sat May 22 14:58:24 2010 +0200
+++ b/util/sasl/scram.lua	Sat May 22 19:04:53 2010 +0200
@@ -92,6 +92,18 @@
 	return username;
 end
 
+function saltedPasswordSHA1(password, salt, iteration_count)
+	local salted_password
+	if type(password) ~= "string" and type(salt) ~= "string" and type(iteration_count) ~= "number" then
+		return false, "inappropriate argument types"
+	end
+	if iteration_count < 4096 then
+		log("warning", "Iteration count < 4096 which is the suggested minimum according to RFC 5802.")
+	end
+
+	return true, Hi(hmac_sha1, password, salt, iteration_count);
+end
+
 local function scram_gen(hash_name, H_f, HMAC_f)
 	local function scram_hash(self, message)
 		if not self.state then self["state"] = {} end
@@ -133,9 +145,16 @@
 					log("debug", "Password violates SASLprep.");
 					return "failure", "not-authorized", "Invalid password."
 				end
+
 				self.state.salt = generate_uuid();
 				self.state.iteration_count = default_i;
-				self.state.salted_password = Hi(HMAC_f, password, self.state.salt, default_i);
+
+				local succ = false;
+				succ, self.state.salted_password = saltedPasswordSHA1(password, self.state.salt, default_i, self.state.iteration_count);
+				if not succ then
+					log("error", "Generating salted password failed. Reason: %s", self.state.salted_password);
+					return "failure", "temporary-auth-failure";
+				end
 			elseif self.profile["scram_"..hash_name] then
 				local salted_password, iteration_count, salt, state = self.profile["scram-"..hash_name](self.state.name, self.realm);
 				if state == nil then return "failure", "not-authorized"