Beispiel #1
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
Beispiel #2
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))
Beispiel #3
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
Beispiel #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)
Beispiel #5
0
	def compute_ek_and_mk_factors(self, my_keyid, their_keyid):
		my_public_key = self.my_public_factors[my_keyid]
		their_public_key = self.their_public_factors[their_keyid]
		#self.compute_c_and_m_factors(my_keyid, their_keyid)
		if my_public_key > their_public_key:
			self.end = "high"
			self.sendbyte = 0x01
			self.recvbyte = 0x02
		else:
			self.end = "low"
			self.sendbyte = 0x02
			self.recvbyte = 0x01
		self.send_aes_key = OtrCrypt.h1(self.sendbyte, self.secbytes)[0:16]
		self.send_mac_key = OtrCrypt.get_sha1_bytes(self.send_aes_key)[0:20]
		self.recv_aes_key = OtrCrypt.h1(self.recvbyte, self.secbytes)[0:16]
		self.recv_mac_key = OtrCrypt.get_sha1_bytes(self.recv_aes_key)[0:20]
Beispiel #6
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
Beispiel #7
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)
Beispiel #8
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)
Beispiel #9
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)
Beispiel #10
0
	def hash_my_public_factor_mpi(self, my_keyid=None):
		hash_gxmpi = OtrCrypt.get_sha256_bytes(self.my_public_factor_to_mpi(my_keyid))
		# RCHANGE
		if self.authing: self.replay.check('hash_dh_factor', hash_gxmpi)
		hash_gxmpi_data = _OT.bytes_to_data(hash_gxmpi)
		return hash_gxmpi_data
Beispiel #11
0
	def encrypt_my_public_factor_mpi(self, my_keyid=None):
		enc_gxmpi = OtrCrypt.aes_zero_ctr_crypt(self.r_secret, self.my_public_factor_to_mpi(my_keyid))
		# RCHANGE
		if self.authing: self.replay.check('enc_dh_factor', enc_gxmpi)
		enc_gxmpi_data = _OT.bytes_to_data(enc_gxmpi)
		return enc_gxmpi_data