def deliver_local_key(local_key_packet: bytes, kek: bytes, c_code: bytes, settings: 'Settings', queues: 'QueueDict') -> None: """Deliver encrypted local key to Destination Computer.""" nc_bypass_msg(NC_BYPASS_START, settings) queue_to_nc(local_key_packet, queues[RELAY_PACKET_QUEUE]) while True: print_key("Local key decryption key (to Receiver)", kek, settings) purp_code = ask_confirmation_code("Receiver") if purp_code == c_code.hex(): nc_bypass_msg(NC_BYPASS_STOP, settings) break elif purp_code == "": phase("Resending local key", head=2) queue_to_nc(local_key_packet, queues[RELAY_PACKET_QUEUE]) phase(DONE) print_on_previous_line( reps=(9 if settings.local_testing_mode else 10)) else: m_print([ "Incorrect confirmation code. If Receiver did not receive", "the encrypted local key, resend it by pressing <Enter>." ], head=1) print_on_previous_line( reps=(9 if settings.local_testing_mode else 10), delay=2)
def test_nc_bypass_msg(self, _): settings = Settings(nc_bypass_messages=True) self.assertIsNone(nc_bypass_msg(NC_BYPASS_START, settings)) self.assertIsNone(nc_bypass_msg(NC_BYPASS_STOP, settings))
def new_local_key(contact_list: 'ContactList', settings: 'Settings', queues: 'QueueDict') -> None: """Run local key exchange protocol. Local key encrypts commands and data sent from Source Computer to user's Destination Computer. The key is delivered to Destination Computer in packet encrypted with an ephemeral, symmetric, key encryption key. The check-summed Base58 format key decryption key is typed to Receiver Program manually. This prevents local key leak in following scenarios: 1. CT is intercepted by an adversary on compromised Networked Computer, but no visual eavesdropping takes place. 2. CT is not intercepted by an adversary on Networked Computer, but visual eavesdropping records key decryption key. 3. CT is delivered from Source Computer to Destination Computer directly (bypassing compromised Networked Computer), and visual eavesdropping records key decryption key. Once the correct key decryption key is entered to Receiver Program, it will display the 2-hexadecimal confirmation code generated by the Transmitter Program. The code will be entered back to Transmitter Program to confirm the user has successfully delivered the key decryption key. The protocol is completed with Transmitter Program sending LOCAL_KEY_RDY signal to the Receiver Program, that then moves to wait for public keys from contact. """ try: if settings.traffic_masking and contact_list.has_local_contact(): raise FunctionReturn( "Error: Command is disabled during traffic masking.", head_clear=True) m_print("Local key setup", bold=True, head_clear=True, head=1, tail=1) if not contact_list.has_local_contact(): time.sleep(0.5) key = csprng() hek = csprng() kek = csprng() c_code = os.urandom(CONFIRM_CODE_LENGTH) local_key_packet = LOCAL_KEY_DATAGRAM_HEADER + encrypt_and_sign( plaintext=key + hek + c_code, key=kek) # Deliver local key to Destination computer nc_bypass_msg(NC_BYPASS_START, settings) queue_to_nc(local_key_packet, queues[RELAY_PACKET_QUEUE]) while True: print_key("Local key decryption key (to Receiver)", kek, settings) purp_code = ask_confirmation_code('Receiver') if purp_code == c_code.hex(): nc_bypass_msg(NC_BYPASS_STOP, settings) break elif purp_code == '': phase("Resending local key", head=2) queue_to_nc(local_key_packet, queues[RELAY_PACKET_QUEUE]) phase(DONE) print_on_previous_line( reps=(9 if settings.local_testing_mode else 10)) else: m_print([ "Incorrect confirmation code. If Receiver did not receive", "the encrypted local key, resend it by pressing <Enter>." ], head=1) print_on_previous_line( reps=(9 if settings.local_testing_mode else 10), delay=2) # Add local contact to contact list database contact_list.add_contact(LOCAL_PUBKEY, LOCAL_NICK, bytes(FINGERPRINT_LENGTH), bytes(FINGERPRINT_LENGTH), KEX_STATUS_LOCAL_KEY, False, False, False) # Add local contact to keyset database queues[KEY_MANAGEMENT_QUEUE].put( (KDB_ADD_ENTRY_HEADER, LOCAL_PUBKEY, key, csprng(), hek, csprng())) # Notify Receiver that confirmation code was successfully entered queue_command(LOCAL_KEY_RDY, settings, queues) m_print("Successfully completed the local key exchange.", bold=True, tail_clear=True, delay=1, head=1) os.system(RESET) except (EOFError, KeyboardInterrupt): raise FunctionReturn("Local key setup aborted.", tail_clear=True, delay=1, head=2)