Esempio n. 1
0
	def respond_to_dh_commit(self, msg):
		logging.debug("Responding to DH Commit")
		
		send_dh_key = True
		
		if self.auth.auth_state_is("AUTHSTATE_NONE"):
			# Reply with a D-H Key Message, and transition authstate to AUTHSTATE_AWAITING_REVEALSIG.
			pass # pick it up in the 'if' below
			
		elif self.auth.auth_state_is("AUTHSTATE_AWAITING_DHKEY"):
			#This is the trickiest transition in the whole protocol. It indicates that you have
			# already sent a D-H Commit message to your correspondent, but that he either
			#  didn't receive it, or just didn't receive it yet, and has sent you one as well. 
			#  The symmetry will be broken by comparing the hashed gx you sent in your D-H Commit 
			#  Message with the one you received, considered as 32-byte unsigned big-endian values.
			my_dh_keyid = self.auth.dh_keys.get_my_cur_keyid()
			
			my_hashed_gxmpi = self.auth.dh_keys.hash_my_public_factor_mpi(my_dh_keyid)
			their_hashed_gxmpi = _OT.data_to_bytes(msg.hash_gxmpi_data)
			
			my_hash_as_int = _OT.bytes_to_int(my_hashed_gxmpi)
			their_hash_as_int = _OT.bytes_to_int(their_hashed_gxmpi)
		
			if my_hash_as_int > their_hash_as_int:
				# If yours is the higher hash value:
				# Ignore the incoming D-H Commit message, but resend your D-H Commit message.
				self.auth.dh_keys.mark_my_key_as_used(my_dh_keyid)
				enc_gxmpi_data = self.auth.dh_keys.encrypt_my_public_factor_mpi(my_dh_keyid)
				hash_gxmpi_data = self.auth.dh_keys.hash_my_public_factor_mpi(my_dh_keyid)
				response = self.message_factory().create_dh_commit(enc_gxmpi_data, hash_gxmpi_data)
				self.replay.check('msg_dh_commit', response.jabber_msg.getBody())
				send_dh_key = False
				self.client.send(response.jabber_msg)
							
		if send_dh_key:
			my_dh_keyid = self.auth.dh_keys.get_my_cur_keyid()
			self.auth.dh_keys.mark_my_key_as_used(my_dh_keyid)
		
			# this is g**y formatted as an MPI (4 byte length prepended)	
			# our D-H secret is y (with g**x the shared key is g**(xy))
			gympi = self.auth.dh_keys.my_public_factor_to_mpi(my_dh_keyid)
		
			# SAVE their info
			self.auth.dh_keys.store_their_commitment( _OT.data_to_bytes(msg.enc_gxmpi_data),
													  _OT.data_to_bytes(msg.hash_gxmpi_data) )
		
			# ok, now make dh_key message
			response = self.message_factory().create_dh_key(gympi)
			self.replay.check('msg_dh_key', response.jabber_msg.getBody())
			self.auth.set_auth_state("AUTHSTATE_AWAITING_REVEALSIG")
			self.client.send(response.jabber_msg)
				
		return None # nothing for user
Esempio n. 2
0
	def respond_to_reveal_sig(self, msg):
		logging.debug("Responding to Reveal Sig")
		if not self.auth.auth_state_is("AUTHSTATE_AWAITING_REVEALSIG"):
			return None # nothing for user
			
		# Now decrypt and check their DH factor 
		my_dh_keyid = self.auth.dh_keys.get_my_cur_keyid()
		it_checks_out = self.auth.dh_keys.decrypt_their_public_factor( _OT.data_to_bytes(msg.revealed_key_data) )
		
		if not it_checks_out:
			err_msg = self.message_factory()
			err_msg.create_error('Committed DH factor incorrect')
			self.client.send(err_msg.jabber_msg)
			return None # nothing for user
			raise Exception('stop here - committed DH factor incorrect')
			
		# calculate the factors we'll need
		self.auth.dh_keys.compute_c_and_m_factors()
		
		# check their sig
		it_checks_out = self.auth.check_their_sig(_OT.data_to_bytes(msg.enc_sig_data), msg.sig_mac)
		
		if not it_checks_out:
			err_msg = self.message_factory()
			err_msg.create_error('Signature incorrect')
			self.client.send(err_msg.jabber_msg)
			return None # nothing for user
			#raise Exception('stop here - signature incorrect')
		
		# ok, now make our sig message
		# load DSA key
		self.auth.dsa_keys.load_my_key()
				
		self.auth.compute_my_M_and_X_values(usePrimes=True)
		enc_sig_data = self.auth.get_enc_sig()
		sig_mac = self.auth.get_enc_sig_mac(usePrimes=True)
		
		response = self.message_factory().create_signature(enc_sig_data, sig_mac)
		
		self.replay.check('msg_signature', response.jabber_msg.getBody())
		
		self.client.send(response.jabber_msg)
		
		self.auth.set_auth_state("AUTHSTATE_NONE")
		self.auth.set_message_state("MSGSTATE_ENCRYPTED")
		self.auth.dh_keys.reset_session()
		self.auth.authing = False
		self.auth.dh_keys.authing = False
		
		return None # nothing for user
Esempio n. 3
0
	def respond_to_signature(self, msg):
		logging.debug("Responding to Signiature")
		
		if not self.auth.auth_state_is("AUTHSTATE_AWAITING_SIG"):
			return None # nothing for user
		
		# check their sig
		it_checks_out = self.auth.check_their_sig(_OT.data_to_bytes(msg.enc_sig_data), msg.sig_mac, usePrimes=True)
		
		if not it_checks_out:
			err_msg = self.message_factory()
			err_msg.create_error('Signature incorrect')
			self.client.send(err_msg.jabber_msg)
			return None # nothing for user
			#raise Exception('stop here - signature incorrect')
		
		self.auth.set_auth_state("AUTHSTATE_NONE")
		self.auth.set_message_state("MSGSTATE_ENCRYPTED")
		self.auth.dh_keys.reset_session()
		self.auth.authing = False
		self.auth.dh_keys.authing = False
		
		logging.debug( "SUCESSFULLY AUTHENTICATED!" )
		
		return None
Esempio n. 4
0
	def receive_data_message(self, msg):
		#global memo
		self.my_sess_keyid = _OT.bytes_to_int(msg.recipient_keyid)
		self.their_sess_keyid = _OT.bytes_to_int(msg.sender_keyid)
		logging.debug( "KEYIDS %d %d " % (self.my_sess_keyid, self.their_sess_keyid))
		if len(msg.next_dh) > 4:
			logging.debug( "GOT NEXT DH" )
			logging.debug( msg.next_dh )
			self.associate_their_keyid(self.their_sess_keyid+1, _OT.mpi_to_int(msg.next_dh))
		self.update_next_counter(self.my_sess_keyid, self.their_sess_keyid, _OT.bytes_to_int(msg.counter))
		logging.debug( (msg.counter, _OT.int_to_bytes(self.ctr)) )
		self.compute_c_and_m_factors(self.my_sess_keyid, self.their_sess_keyid)
		self.compute_ek_and_mk_factors(self.my_sess_keyid, self.their_sess_keyid)
	
		#assert memo.sender_keyid == msg.sender_keyid
		#assert memo.recipient_keyid == msg.recipient_keyid
		#assert memo.next_dh == msg.next_dh
		#assert memo.counter == msg.counter
		#assert memo.enc_msg == _OT.data_to_bytes(msg.enc_msg)
		
		T = [0,2,3, msg.flags[0]] # protocol version and type code 
		# my_keyid
		T.extend( msg.sender_keyid )
		# their_keyid
		T.extend( msg.recipient_keyid )
		# next_dh
		T.extend( msg.next_dh )
		# ctr
		T.extend( msg.counter )
		# enc_msg
		logging.debug(("ENC DATA: ", msg.enc_msg))
		T.extend( msg.enc_msg )
		
		#assert memo.T == T
		#print memo.sender_factor
		
		#print "RECVER"
		#for x in sorted(self.their_public_factors.keys()):
		#	print (x, self.their_public_factor_to_mpi(x)) 
		#r = raw_input()
		
		#assert memo.sender_factor == self.their_public_factor_to_mpi(self.their_sess_keyid)
		#assert memo.recipient_factor == self.my_public_factor_to_mpi(self.my_sess_keyid)
		#assert memo.secbytes == self.secbytes
		# compute MAC_mk(T)
		auth_check = OtrCrypt.get_sha1_hmac(self.recv_mac_key, T)
		
		if auth_check != msg.authenticator:
			logging.debug( ("got: ", auth_check) )
			logging.debug( ("exp: ", msg.authenticator) )
			#print self.recv_mac_key, self.send_mac_key
			#print memo.send_mac_key
			raise Exception("mac fail")
		
		return OtrCrypt.aes_ctr_crypt(self.recv_aes_key, _OT.data_to_bytes(msg.enc_msg), msg.counter)