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
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
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}
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
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
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))
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])
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
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
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
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))
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
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)
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
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
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
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
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)
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
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)
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))
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])
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
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)
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
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)
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
def get_enc_sig(self): return _OT.bytes_to_data(self.my_enc_sig)
def payload_to_bytes(self, payload): return _OT.string_to_bytes(base64.b64decode(payload))
def verify(key, data, r, s): return key.verify(_OT.bytes_to_string(data), (r, s))