util/sasl/scram.lua
changeset 5869 35780ef2d689
parent 5868 bc37c6758f3a
child 5870 61f748d363e1
equal deleted inserted replaced
5868:bc37c6758f3a 5869:35780ef2d689
   110 		if not state then
   110 		if not state then
   111 			-- we are processing client_first_message
   111 			-- we are processing client_first_message
   112 			local client_first_message = message;
   112 			local client_first_message = message;
   113 
   113 
   114 			-- TODO: fail if authzid is provided, since we don't support them yet
   114 			-- TODO: fail if authzid is provided, since we don't support them yet
   115 			local gs2_header, gs2_cbind_flag, gs2_cbind_name, authzid, name, clientnonce
   115 			local gs2_header, gs2_cbind_flag, gs2_cbind_name, authzid, client_first_message_bare, name, clientnonce
   116 				= client_first_message:match("^(([ynp])=?([%a%-]*),(.*),)n=(.*),r=([^,]*).*");
   116 				= s_match(client_first_message, "^(([pny])=?([^,]*),([^,]*),)(m?=?[^,]*,?n=([^,]*),r=([^,]*),?.*)$");
   117 
   117 
   118 			if not gs2_cbind_flag then
   118 			if not gs2_cbind_flag then
   119 				return "failure", "malformed-request";
   119 				return "failure", "malformed-request";
   120 			end
   120 			end
   121 
   121 
   183 				name = name;
   183 				name = name;
   184 				nonce = nonce;
   184 				nonce = nonce;
   185 
   185 
   186 				server_key = server_key;
   186 				server_key = server_key;
   187 				stored_key = stored_key;
   187 				stored_key = stored_key;
   188 				client_first_message = client_first_message;
   188 				client_first_message_bare = client_first_message_bare;
   189 				server_first_message = server_first_message;
   189 				server_first_message = server_first_message;
   190 			}
   190 			}
   191 			return "challenge", server_first_message
   191 			return "challenge", server_first_message
   192 		else
   192 		else
   193 			-- we are processing client_final_message
   193 			-- we are processing client_final_message
   194 			local client_final_message = message;
   194 			local client_final_message = message;
   195 
   195 
   196 			local channelbinding, nonce, proof = client_final_message:match("^c=(.*),r=(.*),.*p=(.*)");
   196 			local client_final_message_without_proof, channelbinding, nonce, proof
       
   197 				= s_match(client_final_message, "(c=([^,]*),r=([^,]*),?.-),p=(.*)$");
   197 
   198 
   198 			if not proof or not nonce or not channelbinding then
   199 			if not proof or not nonce or not channelbinding then
   199 				return "failure", "malformed-request", "Missing an attribute(p, r or c) in SASL message.";
   200 				return "failure", "malformed-request", "Missing an attribute(p, r or c) in SASL message.";
   200 			end
   201 			end
   201 
   202 
   214 			end
   215 			end
   215 
   216 
   216 			local ServerKey = state.server_key;
   217 			local ServerKey = state.server_key;
   217 			local StoredKey = state.stored_key;
   218 			local StoredKey = state.stored_key;
   218 
   219 
   219 			local AuthMessage = "n=" .. s_match(state.client_first_message,"n=(.+)") .. "," .. state.server_first_message .. "," .. s_match(client_final_message, "(.+),p=.+")
   220 			local AuthMessage = state.client_first_message_bare .. "," .. state.server_first_message .. "," .. client_final_message_without_proof
   220 			local ClientSignature = HMAC_f(StoredKey, AuthMessage)
   221 			local ClientSignature = HMAC_f(StoredKey, AuthMessage)
   221 			local ClientKey = binaryXOR(ClientSignature, base64.decode(proof))
   222 			local ClientKey = binaryXOR(ClientSignature, base64.decode(proof))
   222 			local ServerSignature = HMAC_f(ServerKey, AuthMessage)
   223 			local ServerSignature = HMAC_f(ServerKey, AuthMessage)
   223 
   224 
   224 			if StoredKey == H_f(ClientKey) then
   225 			if StoredKey == H_f(ClientKey) then