Comparison

util/sasl/scram.lua @ 3206:ff1d3f751da1

util.sasl.scram: Authenticate clients by calculated StoredKey instead of ClientProof.
author Tobias Markmann <tm@ayena.de>
date Tue, 08 Jun 2010 11:00:26 +0200
parent 3205:2dcd826bbbc6
child 3374:ce52f1d5cb74
comparison
equal deleted inserted replaced
3205:2dcd826bbbc6 3206:ff1d3f751da1
155 155
156 self.state.salt = generate_uuid(); 156 self.state.salt = generate_uuid();
157 self.state.iteration_count = default_i; 157 self.state.iteration_count = default_i;
158 158
159 local succ = false; 159 local succ = false;
160 succ, self.state.salted_password = saltedPasswordSHA1(password, self.state.salt, default_i, self.state.iteration_count); 160 succ, self.state.stored_key, self.state.server_key = getAuthenticationDatabaseSHA1(password, self.state.salt, default_i, self.state.iteration_count);
161 if not succ then 161 if not succ then
162 log("error", "Generating salted password failed. Reason: %s", self.state.salted_password); 162 log("error", "Generating authentication database failed. Reason: %s", self.state.stored_key);
163 return "failure", "temporary-auth-failure"; 163 return "failure", "temporary-auth-failure";
164 end 164 end
165 elseif self.profile["scram_"..hashprep(hash_name)] then 165 elseif self.profile["scram_"..hashprep(hash_name)] then
166 local salted_password, iteration_count, salt, state = self.profile["scram_"..hashprep(hash_name)](self.state.name, self.realm); 166 local stored_key, server_key, iteration_count, salt, state = self.profile["scram_"..hashprep(hash_name)](self.state.name, self.realm);
167 if state == nil then return "failure", "not-authorized" 167 if state == nil then return "failure", "not-authorized"
168 elseif state == false then return "failure", "account-disabled" end 168 elseif state == false then return "failure", "account-disabled" end
169 169
170 self.state.salted_password = salted_password; 170 self.state.stored_key = stored_key;
171 self.state.server_key = server_key;
171 self.state.iteration_count = iteration_count; 172 self.state.iteration_count = iteration_count;
172 self.state.salt = salt 173 self.state.salt = salt
173 end 174 end
174 175
175 local server_first_message = "r="..self.state.clientnonce..self.state.servernonce..",s="..base64.encode(self.state.salt)..",i="..self.state.iteration_count; 176 local server_first_message = "r="..self.state.clientnonce..self.state.servernonce..",s="..base64.encode(self.state.salt)..",i="..self.state.iteration_count;
187 188
188 if self.state.nonce ~= self.state.clientnonce..self.state.servernonce then 189 if self.state.nonce ~= self.state.clientnonce..self.state.servernonce then
189 return "failure", "malformed-request", "Wrong nonce in client-final-message."; 190 return "failure", "malformed-request", "Wrong nonce in client-final-message.";
190 end 191 end
191 192
192 local SaltedPassword = self.state.salted_password; 193 local ServerKey = self.state.server_key;
193 local ClientKey = HMAC_f(SaltedPassword, "Client Key") 194 local StoredKey = self.state.stored_key;
194 local ServerKey = HMAC_f(SaltedPassword, "Server Key") 195
195 local StoredKey = H_f(ClientKey)
196 local AuthMessage = "n=" .. s_match(self.state.client_first_message,"n=(.+)") .. "," .. self.state.server_first_message .. "," .. s_match(client_final_message, "(.+),p=.+") 196 local AuthMessage = "n=" .. s_match(self.state.client_first_message,"n=(.+)") .. "," .. self.state.server_first_message .. "," .. s_match(client_final_message, "(.+),p=.+")
197 local ClientSignature = HMAC_f(StoredKey, AuthMessage) 197 local ClientSignature = HMAC_f(StoredKey, AuthMessage)
198 local ClientProof = binaryXOR(ClientKey, ClientSignature) 198 local ClientKey = binaryXOR(ClientSignature, base64.decode(self.state.proof))
199 local ServerSignature = HMAC_f(ServerKey, AuthMessage) 199 local ServerSignature = HMAC_f(ServerKey, AuthMessage)
200 200
201 if base64.encode(ClientProof) == self.state.proof then 201 if StoredKey == H_f(ClientKey) then
202 local server_final_message = "v="..base64.encode(ServerSignature); 202 local server_final_message = "v="..base64.encode(ServerSignature);
203 self["username"] = self.state.name; 203 self["username"] = self.state.name;
204 return "success", server_final_message; 204 return "success", server_final_message;
205 else 205 else
206 return "failure", "not-authorized", "The response provided by the client doesn't match the one we calculated."; 206 return "failure", "not-authorized", "The response provided by the client doesn't match the one we calculated.";