def Hi(self, text, salt, iterations): text = bytes(text) ui1 = self.HMAC(text, salt + b'\0\0\0\01') ui = ui1 for i in range(iterations - 1): ui1 = self.HMAC(text, ui1) ui = XOR(ui, ui1) return ui
def process_2(self, challenge): self.step = 2 data = self.parse(challenge) if b'm' in data: raise SASLCancelled('Received reserved attribute.') salt = b64decode(data[b's']) iteration_count = int(data[b'i']) nonce = data[b'r'] if nonce[:len(self.cnonce)] != self.cnonce: raise SASLCancelled('Invalid nonce') cbind_data = b'' if self.use_channel_binding: cbind_data = self.credentials['channel_binding'] cbind_input = self.gs2_header + cbind_data channel_binding = b'c=' + b64encode(cbind_input).replace(b'\n', b'') client_final_message_without_proof = channel_binding + b',' + \ b'r=' + nonce salted_password = self.Hi(self.credentials['password'], salt, iteration_count) client_key = self.HMAC(salted_password, b'Client Key') stored_key = self.H(client_key) auth_message = self.client_first_message_bare + b',' + \ challenge + b',' + \ client_final_message_without_proof client_signature = self.HMAC(stored_key, auth_message) client_proof = XOR(client_key, client_signature) server_key = self.HMAC(salted_password, b'Server Key') self.server_signature = self.HMAC(server_key, auth_message) client_final_message = client_final_message_without_proof + \ b',p=' + b64encode(client_proof) return client_final_message