Example #1
0
	def respond_to_data(self, msg):
		logging.debug("Responding to Data")
		if self.auth.message_state_is("MSGSTATE_ENCRYPTED"):
			# Verify the info in the message
			
			dec_msg = self.auth.dh_keys.receive_data_message(msg)
			logging.debug( dec_msg )
			if len(dec_msg) > 0:
				logging.debug( "DECRYPTED: "+_OT.bytes_to_string(dec_msg) )
				if self.echolalic:
					msg = self.message_factory().make_jabber_message(_OT.bytes_to_string(dec_msg))
					self.process_outgoing(msg)
			# If verification succeeds:
			
			# Decrypt the message and display the human-readable part (if non-empty) to the user.
			
			# Update the D-H encryption keys, if necessary.
			
			# If you have not sent a message to this correspondent in some (configurable) time, 
			# send a "heartbeat" message, consisting of a Data Message encoding an empty plaintext. 
			# The heartbeat message should have the IGNORE_UNREADABLE flag set.
			
			# If the received message contains a TLV type 1, forget all encryption keys 
			# for this correspondent, and transition msgstate to MSGSTATE_FINISHED.
			
		else:
			# Inform the user that an unreadable encrypted message was received, and reply with an Error Message.
			# TODO check for heartbeat messages
			
			logging.debug( "Not ready!" )
			pass
			
		return None
Example #2
0
 def format_key(key):
     bytes = list(OtrConstants["dsa_code_bytes"])
     bytes.extend(_OT.int_to_mpi(key.p))
     bytes.extend(_OT.int_to_mpi(key.q))
     bytes.extend(_OT.int_to_mpi(key.g))
     bytes.extend(_OT.int_to_mpi(key.y))
     return bytes
Example #3
0
	def get_tlv(self):
		tlv_type = _OT.bytes_to_int(self.get_short())
		tlv_len = _OT.bytes_to_int(self.get_short())
		value = []
		if tlv_len > 0:
			value.extend(self.get_n_bytes(tlv_len))
		return {'type': tlv_type, 'length': tlv_len, 'value': value}
Example #4
0
	def create_data(self, flags, sender_keyid, recipient_keyid, next_dh,
					counter, enc_msg, authenticator, old_mac_keys):
		self.type = "data"
		#self.vars = (
		#	("protocol_version", "short"),
		#	("message_type", "byte"),
		#	("flags", "byte"),
		#	("sender_keyid", "int"),
		#	("recipient_keyid", "int"),
		#	("next_dh", "mpi"),
		#	("counter", "ctr"),
		#	("enc_msg", "data"),
		#	("authenticator", "mac"),
		#	("old_mac_keys", "data")
		#)
		
		if ( not len(flags) == 1 ):
			raise Exception('Invalid data format: flags')
		
		if ( not len(sender_keyid) == 4 ):
			raise Exception('Invalid data format: sender_keyid')
		
		if ( not len(recipient_keyid) == 4 ):
			raise Exception('Invalid data format: recipient_keyid')
		
		if ( not _OT.check_mpi(next_dh) ):
			raise Exception('Invalid data format: next_dh')
		
		if (not len(counter) == 8 ):
			raise Exception('Invalid data format: counter')
		
		if ( not _OT.check_data(enc_msg) ):
			raise Exception('Invalid data format: enc_msg')
		
		if ( not _OT.check_mac(authenticator) ):
			raise Exception('Invalid data format: authenticator')
		
		if ( not _OT.check_data(old_mac_keys) ):
			raise Exception('Invalid data format: old_mac_keys')
		
		self.protocol_version = list(OtrConstants["version_2_bytes"])
		self.message_type = [OtrConstants["code_data"]]
		
		self.flags = flags
		self.sender_keyid = sender_keyid
		self.recipient_keyid = recipient_keyid
		self.next_dh = next_dh
		self.counter = counter
		self.enc_msg = enc_msg
		self.authenticator = authenticator
		self.old_mac_keys = old_mac_keys
		
		message_data = self.protocol_version + self.message_type + \
						flags + sender_keyid + recipient_keyid + \
						next_dh + counter + enc_msg + authenticator + \
						old_mac_keys
		self.pack_message(message_data)
		self.parsed_ok = True
		return self
Example #5
0
 def sign(self, data):
     if self.replay.can_replay("k"):
         k = self.replay.data["k"]
     else:
         k = random.SystemRandom().randint(2, self.my_private_key.q - 1)
     r, s = self.my_private_key.sign(_OT.bytes_to_string(data), k)
     ra = _OT.zero_pad(_OT.int_to_bytes(r), self.my_q_len)
     sa = _OT.zero_pad(_OT.int_to_bytes(s), self.my_q_len)
     return ra + sa
Example #6
0
	def encrypt_data_message(self, msg):
		#global memo
		# encrypt the message
		counter = _OT.zero_pad(_OT.int_to_bytes(self.ctr), 8)
		enc_msg = OtrCrypt.aes_ctr_crypt(self.send_aes_key, msg, self.ctr)
		
		memo.enc_msg = enc_msg
		
		flags = [0x00]
		
		#memo.flags = flags
		
		# generate T = (my_keyid, their_keyid, next_dh, ctr, AES-CTR_ek,ctr(msg))
		T = [0,2,3, flags[0]] # protocol version and msg code
		# my_keyid
		sender_keyid = _OT.zero_pad(_OT.int_to_bytes(self.my_sess_keyid), 4)
		#memo.sender_keyid = sender_keyid
		T.extend( sender_keyid )
		# their_keyid
		recipient_keyid = _OT.zero_pad(_OT.int_to_bytes(self.their_sess_keyid), 4)
		#memo.recipient_keyid = recipient_keyid
		T.extend( recipient_keyid )
		# next_dh
		next_dh = _OT.int_to_mpi(self.next_dh)
		#memo.next_dh = next_dh
		T.extend( next_dh )
		# ctr
		#memo.counter = counter
		T.extend( counter )
		# enc_msg
		T.extend( _OT.bytes_to_data(enc_msg) )
		
		#memo.T = T
		
		# compute MAC_mk(T)
		authenticator = OtrCrypt.get_sha1_hmac(self.send_mac_key, T)
		
		#memo.authenticator = authenticator
		#memo.old_mac_keys = self.old_mac_keys
		
		#memo.send_mac_key = self.send_mac_key
		#memo.recv_mac_key = self.recv_mac_key
		#memo.send_aes_key = self.send_aes_key
		#memo.recv_aes_key = self.recv_aes_key
		
		#memo.secbytes = self.secbytes
		#memo.sender_factor = self.my_public_factor_to_mpi(self.my_sess_keyid)
		
		#print "SENDER"
		#for x in sorted(self.my_public_factors.keys()):
		#	print (x, self.my_public_factor_to_mpi(x)) 
		#r = raw_input()
		
		#memo.recipient_factor = self.their_public_factor_to_mpi(self.their_sess_keyid)
		return (flags, sender_keyid, recipient_keyid, next_dh, counter,
			_OT.bytes_to_data(enc_msg), authenticator, _OT.bytes_to_data(self.old_mac_keys))
Example #7
0
	def aes_ctr_crypt(key, data_orig, ctr_val):
		data = [x for x in data_orig]
		AESr = AES.new(_OT.bytes_to_cbytes(key), AES.MODE_CTR, counter=OtrCrypt.aes_counter(ctr_val))
		# need to fill to a multiple of 16; since it is in 
		# counter mode, we can just ignore the end of the encrypted output
		fill_len = (16 - (len(data) % 16)) % 16
		data.extend([0]*fill_len)
		# do the encryption
		enc_str = AESr.encrypt(_OT.bytes_to_cbytes(data))
		return _OT.string_to_bytes(enc_str[:-fill_len])
Example #8
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
Example #9
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
Example #10
0
	def check_their_sig(self, enc_sig, sig_mac, usePrimes=False):
		my_dh_key = self.dh_keys.get_my_cur_keyid()
		if usePrimes:
			cKey = self.dh_keys.cprime
			m1Key = self.dh_keys.m1prime
			m2Key = self.dh_keys.m2prime
		else:
			cKey = self.dh_keys.c
			m1Key = self.dh_keys.m1
			m2Key = self.dh_keys.m2
		
		sig = OtrCrypt.aes_zero_ctr_crypt(cKey, enc_sig)
		#print sig
		
		byte_reader = ByteStreamReader(sig)
		
		their_dsa_key = byte_reader.get_pubkey()
		if their_dsa_key["cipher_code"] != list(OtrConstants["dsa_code_bytes"]):
			return False
		
		# now keyid
		their_dh_keyid = _OT.bytes_to_int(byte_reader.get_int())
		self.dh_keys.associate_their_keyid(their_dh_keyid)
		
		# load their DSA public key - (y,g,p,q)
		their_dsa_key_tup = (
			_OT.mpi_to_int(their_dsa_key["y_mpi"]),
			_OT.mpi_to_int(their_dsa_key["g_mpi"]),
			_OT.mpi_to_int(their_dsa_key["p_mpi"]),
			_OT.mpi_to_int(their_dsa_key["q_mpi"])
		)
		self.dsa_keys.load_their_key(their_dsa_key_tup)
		
		# compute their M factor
		self.compute_their_M_factor(usePrimes=usePrimes)
		
		# now load their signed M factor
		q_len = their_dsa_key["q_len"]
		M_sig_r_factor = _OT.bytes_to_int(byte_reader.get_n_bytes(q_len))
		M_sig_s_factor = _OT.bytes_to_int(byte_reader.get_n_bytes(q_len))
		
		assert (byte_reader.consumed_all())
	
		if not OtrDSA.verify(self.dsa_keys.their_public_key, self.their_M, 
								M_sig_r_factor, M_sig_s_factor):
			logging.debug("DID NOT VERIFY")
			return False
		
		# now check their MAC
		calc_sig_mac = OtrCrypt.get_sha256_hmac_160(m2Key, _OT.bytes_to_data(enc_sig))
		if calc_sig_mac != sig_mac:
			logging.debug( "MAC INCORRECT" )
			#print enc_sig
			#print calc_sig_mac
			#print sig_mac
			return False
		
		# alright, looks like everything checks out 
		return True
Example #11
0
	def store_their_public_factor(self, their_public_factor):
		self.their_public_factor_temp = their_public_factor
		self.their_cur_keyid = None
		# RCHANGE
		if self.authing and self.my_cur_keyid==1: 
			our_secret_key = pow(their_public_factor, self.my_private_keys[1], self.dh_mod)
			self.replay.check('s', _OT.int_to_bytes(our_secret_key))
Example #12
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
Example #13
0
	def compute_c_and_m_factors(self, my_keyid=None, their_keyid=None):
		#Write the value of s as a minimum-length MPI, as specified above
		# (4-byte big-endian len, len-byte big-endian value). 
		# Let this (4+len)-byte value be "secbytes".
		self.secbytes = _OT.int_to_mpi(self.make_shared_key(my_keyid, their_keyid))
		
		#For a given byte b, define h2(b) to be the 256-bit output of the SHA256 hash of the 
		# (5+len) bytes consisting of the byte b, followed by secbytes.
		
		#Let ssid be the first 64 bits of h2(0x00).
		self.ssid = OtrCrypt.h2(0x00, self.secbytes)[0:0+8]
		#Let c be the first 128 bits of h2(0x01), and let c' be the second 128 bits of h2(0x01).
		t = OtrCrypt.h2(0x01, self.secbytes)
		
		self.c = t[0:0+16]
		if self.authing: self.replay.check('c', self.c)
		
		self.cprime = t[16:16+16]
		if self.authing: self.replay.check('cp', self.cprime)
		
		#Let m1 be h2(0x02).
		self.m1 = OtrCrypt.h2(0x02, self.secbytes)
		if self.authing: self.replay.check('m1', self.m1)
		
		#Let m2 be h2(0x03).
		self.m2 = OtrCrypt.h2(0x03, self.secbytes)
		if self.authing: self.replay.check('m2', self.m2)
		
		#Let m1' be h2(0x04).
		self.m1prime = OtrCrypt.h2(0x04, self.secbytes)
		if self.authing: self.replay.check('m1p', self.m1prime)
		
		#Let m2' be h2(0x05).
		self.m2prime = OtrCrypt.h2(0x05, self.secbytes)
		if self.authing: self.replay.check('m2p', self.m2prime)
Example #14
0
	def get_enc_sig_mac(self, usePrimes=False):
		if usePrimes:
			m2Key = self.dh_keys.m2prime
		else:
			m2Key = self.dh_keys.m2
		enc_sig_mac = OtrCrypt.get_sha256_hmac_160(m2Key, _OT.bytes_to_data(self.my_enc_sig))
		self.replay.check('hash_enc_X', enc_sig_mac)
		return enc_sig_mac
Example #15
0
	def create_dh_commit(self, enc_gxmpi_data, hash_gxmpi_data):
		self.type = "dh_commit"
		
		self.protocol_version = list(OtrConstants["version_2_bytes"])
		self.message_type = [OtrConstants["code_dh_commit"]]
		self.enc_gxmpi_data = enc_gxmpi_data
		self.hash_gxmpi_data = hash_gxmpi_data
		
		if ( not _OT.check_data(enc_gxmpi_data) or 
		     not _OT.check_data(hash_gxmpi_data) ):
			raise Exception('Invalid data format')
		
		message_data = self.protocol_version + self.message_type + \
						self.enc_gxmpi_data + self.hash_gxmpi_data
		self.pack_message(message_data)
		self.parsed_ok = True
		return self
Example #16
0
	def decrypt_their_public_factor(self, r_secret):
		self.r_secret = r_secret
		their_public_factor_mpi = \
			OtrCrypt.aes_zero_ctr_crypt(r_secret, self.enc_gxmpi)
		calculated_hash = OtrCrypt.get_sha256_bytes(their_public_factor_mpi)
		if calculated_hash == self.hash_gxmpi:
			self.store_their_public_factor(_OT.mpi_to_int(their_public_factor_mpi))
			return True
		else:
			return False
Example #17
0
	def create_signature(self, enc_sig_data, sig_mac):
		self.type = "signature"
		self.protocol_version = list(OtrConstants["version_2_bytes"])
		self.message_type = [OtrConstants["code_signature"]] 
		
		self.enc_sig_data = enc_sig_data
		self.sig_mac = sig_mac
		
		if ( not _OT.check_data(enc_sig_data) ):
			raise Exception('Invalid data format')
		
		if ( not _OT.check_mac(sig_mac) ):
			raise Exception('Invalid MAC')
		
		message_data = self.protocol_version + self.message_type + \
						enc_sig_data + sig_mac
		self.pack_message(message_data)
		self.parsed_ok = True
		return self
Example #18
0
	def compute_their_M_factor(self, usePrimes=False):
		my_dh_keyid = self.dh_keys.get_my_cur_keyid()
		their_dh_keyid = self.dh_keys.get_their_cur_keyid()
		if usePrimes:
			m1PrimeKey = self.dh_keys.m1prime
		else:
			m1PrimeKey = self.dh_keys.m1
			
		# Compute the 32-byte value MA to be the SHA256-HMAC of the following data, using the key m1':
		mbytes = []
		# gy (MPI)
		mbytes.extend( self.dh_keys.their_public_factor_to_mpi(their_dh_keyid) )
		# gx (MPI)
		mbytes.extend( self.dh_keys.my_public_factor_to_mpi(my_dh_keyid) )
		# pubA (PUBKEY)
		mbytes.extend( OtrDSA.format_key(self.dsa_keys.their_public_key) )
		# keyidA (INT)
		keyid = _OT.zero_pad(_OT.int_to_bytes(their_dh_keyid), 4)
		mbytes.extend( keyid )
		self.their_M = OtrCrypt.get_sha256_hmac(m1PrimeKey, mbytes)
Example #19
0
	def process_outgoing(self, msg):
		logging.debug("Outgoing")
		if self.auth.message_state_is("MSGSTATE_ENCRYPTED"):
			self.auth.dh_keys.prepare_session_to_send()
			vars = self.auth.dh_keys.encrypt_data_message(_OT.string_to_bytes(msg.getBody()))
			logging.debug( vars )
			#r = raw_input()
			enc_msg = self.message_factory().create_data(*vars)
			self.client.send(enc_msg.jabber_msg)
		else:
			self.client.send(msg)
		return msg
Example #20
0
	def compute_my_M_and_X_values(self, usePrimes=False):
		my_dh_keyid = self.dh_keys.get_my_cur_keyid()
		if usePrimes:
			cKey = self.dh_keys.cprime
			m1Key = self.dh_keys.m1prime
		else:
			cKey = self.dh_keys.c
			m1Key = self.dh_keys.m1
		
		# Compute the 32-byte value MB to be the SHA256-HMAC of the following data, using the key m1:
		mbytes = []
		# gx (MPI)
		mbytes.extend( self.dh_keys.my_public_factor_to_mpi(my_dh_keyid) )
		# gy (MPI)
		mbytes.extend( self.dh_keys.their_public_factor_to_mpi() )
		# pubB (PUBKEY)
		mbytes.extend( OtrDSA.format_key(self.dsa_keys.my_public_key) )
		# keyidB (INT)
		keyid = _OT.zero_pad(_OT.int_to_bytes(my_dh_keyid), 4)
		mbytes.extend( keyid )
		self.replay.check('M', mbytes)
		my_M = OtrCrypt.get_sha256_hmac(m1Key, mbytes)
		self.replay.check('hash_M', my_M)
		
		# Let XB be the following structure:
		xbytes = []
		# pubB (PUBKEY)
		xbytes.extend( OtrDSA.format_key(self.dsa_keys.my_public_key) )
		# keyidB (INT)
		xbytes.extend( keyid )
		# sigB(MB) (SIG)
		# This is the signature, using the private part of the key pubB, of the 32-byte MB 
		# (which does not need to be hashed again to produce the signature).
		xbytes.extend( self.dsa_keys.sign( my_M ) )
		my_X = xbytes
		self.replay.check('X', my_X)
		
		# Encrypt XB using AES128-CTR with key c and initial counter value 0.
		self.my_enc_sig = OtrCrypt.aes_zero_ctr_crypt(cKey, my_X)
		self.replay.check('enc_X', self.my_enc_sig)
Example #21
0
	def load_dsa_key(self):
		assert self.can_replay('dsa_public_key')
		assert self.can_replay('dsa_private_key')
		key = self.data['dsa_public_key']
		priv_key = self.data['dsa_private_key']
		
		key_reader = ByteStreamReader(key)
		
		p = _OT.mpi_to_int(key_reader.get_mpi())
		q = _OT.mpi_to_int(key_reader.get_mpi())
		g = _OT.mpi_to_int(key_reader.get_mpi())
		y = _OT.mpi_to_int(key_reader.get_mpi())
		
		assert (key_reader.consumed_all())
		
		priv_key_reader = ByteStreamReader(priv_key)
		
		x = _OT.mpi_to_int(priv_key_reader.get_mpi())
				
		assert (priv_key_reader.consumed_all())
		
		return DSA.construct((y,g,p,q,x))
Example #22
0
	def make_new_key(self, add_as_seen=False):
		# RCHANGE
		if self.my_cur_keyid==0 and self.replay.can_replay('private_dh_key'):
			x = _OT.int_to_bytes(self.replay.data['private_dh_key'])
		else:
			#r = raw_input("random x")
			x = _OT.make_random_bytes(320/8) # Byte range?
		
		new_keyid = self.my_cur_keyid + 1
		logging.debug( "making new key %d" % new_keyid)
		x_int = _OT.bytes_to_int(x)
		new_factor = pow(self.dh_g, x_int, self.dh_mod)
		
		self.my_private_keys[new_keyid] = x_int
		self.my_public_factors[new_keyid] = new_factor
		self.my_key_has_been_used[new_keyid] = False
		self.my_cur_keyid = new_keyid
		if add_as_seen:
			self.my_most_recently_seen.append(new_keyid)
		#r=raw_input()
		
		# RCHANGE
		if self.authing and self.my_cur_keyid==1: self.replay.check('public_dh_factor', self.my_public_factors[1])
Example #23
0
	def create_dh_key(self, gympi):
		self.type = "dh_key"
		
		self.protocol_version = list(OtrConstants["version_2_bytes"])
		self.message_type = [OtrConstants["code_dh_key"]]
		self.gympi = gympi
		
		if ( not _OT.check_mpi(gympi) ):
			raise Exception('Invalid data format')
		
		message_data = self.protocol_version + self.message_type + \
						self.gympi
		self.pack_message(message_data)
		self.parsed_ok = True
		return self
Example #24
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)
Example #25
0
	def respond_to_dh_key(self, msg):
		logging.debug("Responding to DH Key")
		
		send_reveal_sig = True
		
		my_dh_keyid = self.auth.dh_keys.get_my_cur_keyid()
		
		if self.auth.auth_state_is("AUTHSTATE_AWAITING_DHKEY"):
			# calculate the shared dh key
			their_dh_factor = _OT.mpi_to_int(msg.gympi)
			self.auth.dh_keys.store_their_public_factor(their_dh_factor)
			
			# calculate the factor's we'll need
			self.auth.dh_keys.compute_c_and_m_factors()
		
			# load DSA key
			self.auth.dsa_keys.load_my_key()
		
			self.auth.compute_my_M_and_X_values()
			
		elif self.auth.auth_state_is("AUTHSTATE_AWAITING_SIG"):
			if msg.gympi == self.auth.dh_keys.their_public_factor_to_mpi():
				pass # retransmit reveal sig msg
			else:
				send_reveal_sig = False
		else:
			send_reveal_sig = False
			
		if send_reveal_sig:
			revealed_key_data = self.auth.dh_keys.get_r_secret()
			enc_sig_data = self.auth.get_enc_sig()
			sig_mac = self.auth.get_enc_sig_mac()
			response = self.message_factory().create_reveal_sig(revealed_key_data, enc_sig_data, sig_mac)
			self.replay.check('msg_reveal_sig', response.jabber_msg.getBody())
			self.auth.set_auth_state("AUTHSTATE_AWAITING_SIG")
			self.client.send(response.jabber_msg)
		
		return None # nothing for user
Example #26
0
	def pack_message(self, bytes):
		message_data = _OT.bytes_to_cbytes(bytes)
		message_data_str = base64.b64encode(message_data)
		body_str = "?OTR:" + message_data_str+"."
		self.jabber_msg = self.make_jabber_message(body_str)
Example #27
0
	def get_data(self):
		len_array = self.get_n_bytes(4)
		length = _OT.bytes_to_int(len_array)
		value_array = self.get_n_bytes(length)
		return len_array+value_array
Example #28
0
	def get_enc_sig(self):
		return _OT.bytes_to_data(self.my_enc_sig)
Example #29
0
	def payload_to_bytes(self, payload):
		return _OT.string_to_bytes(base64.b64decode(payload))
Example #30
0
 def verify(key, data, r, s):
     return key.verify(_OT.bytes_to_string(data), (r, s))