Exemplo n.º 1
0
def test_get_current_event():
    try:
        with LogCapture():
            private_key = secrets.token_bytes(32)
            signing_key = SigningKey(private_key)
            public_key_feed_id = signing_key.verify_key.encode()

            content = Content('whateverapp/whateveraction', {
                'oneKey': 'somevalue',
                'someotherkey': 1
            })
            hash_of_content = hashlib.sha256(content.get_as_cbor()).hexdigest()
            hash_of_prev = None
            meta = Meta(public_key_feed_id, 0, hash_of_prev, 'ed25519',
                        ('sha256', hash_of_content))
            signature = signing_key.sign(meta.get_as_cbor())._signature
            event = Event(meta, signature, content).get_as_cbor()

            connector = DatabaseConnector()
            connector.add_event(event)
            result = connector.get_current_event(public_key_feed_id)
            result = Event.from_cbor(result)
        assert result.meta.hash_of_content[1] == meta.hash_of_content[1]
    finally:
        try:
            if os.path.exists('cborDatabase.sqlite'):
                os.remove('cborDatabase.sqlite')
                if os.path.exists('eventDatabase.sqlite'):
                    os.remove('eventDatabase.sqlite')
            else:
                assert False
        except PermissionError:
            print('Database is still in use')
Exemplo n.º 2
0
def start_client():  ## Alice
    #inputs = [sys.stdin]  # Array of all input select has to look for
    # (standard input and socket, does not work on windows)
    print('Successfully connected to other user.')  # message to the client that the connection worked

    print("I AM ALICE")
    alice = Alice(identifier_other='Bob')
    #print("X3DH status:", alice.x3dh_status)
    event_list = cf.get_all_saved_events(1)
    #print('len(event_list):', len(event_list))
    content = None
    if len(event_list) > 0:
        last_event = event_list[-1]
        content, meta = last_event
        feed_id = Meta.from_cbor(meta).feed_id

    if content[0] == 'ratchet/contactInfo':
        if alice.x3dh_status == 0:
            # received_keys = local_sock.recv(224)
            #received_keys = retrieve_msg_local()
            key_bundle_to_send = alice.x3dh_create_key_bundle_from_received_key_bundle(content[1]['key_bundle'])
            # local_sock.send(key_bundle_to_send)
            #send_msg_local(key_bundle_to_send)
            #print('befor send to send:', (key_bundle_to_send, ecf.get_feed_id(), feed_id))
            send_second_Bacnet_prekey_bundle(key_bundle_to_send, ecf.get_feed_id(), feed_id)

    if ecf.get_feed_id() != feed_id:
        own_last_event_sequence_number = function.get_current_seq_no(ecf.get_feed_id())

        own_last_event = Event.from_cbor(function.get_event(ecf.get_feed_id(), own_last_event_sequence_number))
        last_own_message_not_reached = True
        for x in event_list:

            if x[0][0] != 'ratchet/message':
                continue
            if last_own_message_not_reached:
                if x[0][1]['ciphertext'] == own_last_event.content.content[1]['ciphertext']:
                    last_own_message_not_reached = False
                    continue

                continue

            #print(x[0][1]['ciphertext'])
            received_message_raw = expose_message_tcp(x[0][1]['ciphertext'], alice)
            print("Received:", received_message_raw)

    while True:
        try:
            msg = input('Please enter your message: ')
            if msg == 'quit':
                break
            send_Bacnet_msg(encapsulate_message_tcp(alice, msg), feed_id, ecf.get_feed_id())
        except KeyboardInterrupt:
            print('Interrupted')
            sys.exit(0)

    running = True
    sentKeys = False
Exemplo n.º 3
0
def test_event_factory():
    ecf = EventFactory()
    new_event = ecf.next_event('whateverapp/whateveraction', {
        'oneKey': 'somevalue',
        'someotherkey': 1
    })
    connector = DatabaseConnector()
    connector.add_event(new_event)
    result = connector.get_current_event(ecf.get_feed_id())
    result = Event.from_cbor(result)
    assert result.content.content[0] == 'whateverapp/whateveraction'
Exemplo n.º 4
0
def test_get_event():
    try:
        with LogCapture() as log_cap:
            private_key = secrets.token_bytes(32)
            signing_key = SigningKey(private_key)
            public_key_feed_id = signing_key.verify_key.encode()

            content0 = Content('whateverapp/whateveraction', {
                'firstkey': 'somevalue',
                'someotherkey': 3
            })
            hash_of_content = hashlib.sha256(
                content0.get_as_cbor()).hexdigest()
            hash_of_prev = None
            meta = Meta(public_key_feed_id, 0, hash_of_prev, 'ed25519',
                        ('sha256', hash_of_content))
            signature = signing_key.sign(meta.get_as_cbor())._signature
            event = Event(meta, signature, content0).get_as_cbor()

            connector = DatabaseConnector()
            connector.add_event(event)
            meta = Meta(public_key_feed_id, 1, hash_of_prev, 'ed25519',
                        ('sha256', hash_of_content))
            content1 = Content('whateverapp/whateveraction', {
                'secondkey': 'somevalue',
                'someotherkey': 4
            })
            signature = signing_key.sign(meta.get_as_cbor())._signature
            event = Event(meta, signature, content1).get_as_cbor()
            connector.add_event(event)
            content2 = Content('whateverapp/whateveraction', {
                'thirdkey': 'somevalue',
                'someotherkey': 5
            })
            meta = Meta(public_key_feed_id, 2, hash_of_prev, 'ed25519',
                        ('sha256', hash_of_content))
            signature = signing_key.sign(meta.get_as_cbor())._signature
            event = Event(meta, signature, content2).get_as_cbor()
            connector.add_event(event)
            res0 = connector.get_event(public_key_feed_id, 0)
            res1 = connector.get_event(public_key_feed_id, 1)
            res2 = connector.get_event(public_key_feed_id, 2)
            result0 = Event.from_cbor(res0)
            result1 = Event.from_cbor(res1)
            result2 = Event.from_cbor(res2)
        assert result0.content.content == content0.content
        assert result1.content.content == content1.content
        assert result2.content.content == content2.content
        print(log_cap)
    finally:
        try:
            if os.path.exists('cborDatabase.sqlite'):
                os.remove('cborDatabase.sqlite')
                if os.path.exists('eventDatabase.sqlite'):
                    os.remove('eventDatabase.sqlite')
            else:
                assert False
        except PermissionError:
            print('Database is still in use')
def test_get_current_event():
    with session_scope():
        with LogCapture():
            private_key = secrets.token_bytes(32)
            signing_key = SigningKey(private_key)
            public_key_feed_id = signing_key.verify_key.encode()

            content = Content('whateverapp/whateveraction', {
                'oneKey': 'somevalue',
                'someotherkey': 1
            })
            hash_of_content = hashlib.sha256(content.get_as_cbor()).hexdigest()
            hash_of_prev = None
            meta = Meta(public_key_feed_id, 0, hash_of_prev, 'ed25519',
                        ('sha256', hash_of_content))
            signature = signing_key.sign(meta.get_as_cbor())._signature
            event = Event(meta, signature, content).get_as_cbor()

            connector = DatabaseConnector()
            connector.add_event(event)
            result = connector.get_current_event(public_key_feed_id)
            result = Event.from_cbor(result)
        assert result.meta.hash_of_content[1] == meta.hash_of_content[1]
def test_event_factory():
    ecf = EventFactory()
    new_event = ecf.next_event('whateverapp/whateveraction', {
        'oneKey': 'somevalue',
        'someotherkey': 1
    })
    connector = DatabaseConnector(
        path_to_db=
        'C:\\Users\\user\\Google Drive\\Studies\\4. Semester\\30526-01 - Introduction to Internet and Security\\Project\\BACnet\\groups\\07-logStore'
    )
    connector.add_event(new_event)
    result = connector.get_current_event(ecf.get_feed_id())
    result = Event.from_cbor(result)
    assert result.content.content[0] == 'whateverapp/whateveraction'
Exemplo n.º 7
0
def retrieve_new_messages_alice(alice) -> None:
    #print("X3DH status:", alice.x3dh_status)
    event_list = cf.get_all_saved_events(1)
    # print('len(event_list):', len(event_list))
    content = None
    if len(event_list) > 0:
        last_event = event_list[-1]
        content, meta = last_event
        feed_id = Meta.from_cbor(meta).feed_id

    if content[0] == 'ratchet/contactInfo':
        if alice.x3dh_status == 0:
            # received_keys = local_sock.recv(224)
            # received_keys = retrieve_msg_local()
            key_bundle_to_send = alice.x3dh_create_key_bundle_from_received_key_bundle(content[1]['key_bundle'])
            # local_sock.send(key_bundle_to_send)
            # send_msg_local(key_bundle_to_send)
            # print('befor send to send:', (key_bundle_to_send, ecf.get_feed_id(), feed_id))
            send_second_Bacnet_prekey_bundle(key_bundle_to_send, ecf.get_feed_id(), feed_id)
            send_Bacnet_msg(
                encapsulate_message_tcp(alice, "[This is a necessary first message, but you can ignore it.]"), feed_id,
                ecf.get_feed_id())
            send_rsync()
            alice.x3dh_status = 2

    if ecf.get_feed_id() != feed_id:
        own_last_event_sequence_number = function.get_current_seq_no(ecf.get_feed_id())

        own_last_event = Event.from_cbor(function.get_event(ecf.get_feed_id(), own_last_event_sequence_number))
        last_own_message_not_reached = True
        for x in event_list:

            if x[0][0] != 'ratchet/message':
                continue
            if last_own_message_not_reached:
                if x[0][1]['ciphertext'] == own_last_event.content.content[1]['ciphertext']:
                    last_own_message_not_reached = False
                    continue

                continue

            #print(x[0][1]['ciphertext'])
            received_message_raw = expose_message_tcp(x[0][1]['ciphertext'], alice)
            print("Received:", received_message_raw)
def test_get_event():
    with session_scope():
        with LogCapture() as log_cap:
            private_key = secrets.token_bytes(32)
            signing_key = SigningKey(private_key)
            public_key_feed_id = signing_key.verify_key.encode()

            content0 = Content('whateverapp/whateveraction', {
                'firstkey': 'somevalue',
                'someotherkey': 3
            })
            hash_of_content = hashlib.sha256(
                content0.get_as_cbor()).hexdigest()
            hash_of_prev = None
            meta = Meta(public_key_feed_id, 0, hash_of_prev, 'ed25519',
                        ('sha256', hash_of_content))
            signature = signing_key.sign(meta.get_as_cbor())._signature
            event = Event(meta, signature, content0).get_as_cbor()

            connector = DatabaseConnector()
            connector.add_event(event)
            meta = Meta(public_key_feed_id, 1, hash_of_prev, 'ed25519',
                        ('sha256', hash_of_content))
            content1 = Content('whateverapp/whateveraction', {
                'secondkey': 'somevalue',
                'someotherkey': 4
            })
            signature = signing_key.sign(meta.get_as_cbor())._signature
            event = Event(meta, signature, content1).get_as_cbor()
            connector.add_event(event)
            content2 = Content('whateverapp/whateveraction', {
                'thirdkey': 'somevalue',
                'someotherkey': 5
            })
            meta = Meta(public_key_feed_id, 2, hash_of_prev, 'ed25519',
                        ('sha256', hash_of_content))
            signature = signing_key.sign(meta.get_as_cbor())._signature
            event = Event(meta, signature, content2).get_as_cbor()
            connector.add_event(event)
            res0 = connector.get_event(public_key_feed_id, 0)
            res1 = connector.get_event(public_key_feed_id, 1)
            res2 = connector.get_event(public_key_feed_id, 2)
            result0 = Event.from_cbor(res0)
            result1 = Event.from_cbor(res1)
            result2 = Event.from_cbor(res2)
        assert result0.content.content == content0.content
        assert result1.content.content == content1.content
        assert result2.content.content == content2.content
        print(log_cap)
Exemplo n.º 9
0
    def save(self, message, chatID):
        to_save = self.username + "#split:#" + message

        signing_key = SigningKey(self.feed_id)
        public_key_feed_id = signing_key.verify_key.encode(encoder=HexEncoder)
        content = Content('chat/saveMessage', {
            'messagekey': to_save,
            'chat_id': chatID,
            'timestampkey': time.time()
        })
        hash_of_content = hashlib.sha256(content.get_as_cbor()).hexdigest()
        hash_of_prev = None
        meta = Meta(public_key_feed_id, 0, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        self.chat_function.insert_chat_msg(event)

        self.loadChat(
            self.partner
        )  #updating chat, so the send message is also added in the listbox
        self.text_field.delete(0, 'end')
Exemplo n.º 10
0
def retrieve_new_messages_bob(bob) -> None:
    #print("Status:", bob.x3dh_status)
    event_list = cf.get_all_saved_events(1)

    if len(event_list) > 0:
        last_event = event_list[-1]
        content, meta = last_event
        feed_id = Meta.from_cbor(meta).feed_id

    if ecf.get_feed_id() != feed_id:
        own_last_event_sequence_number = function.get_current_seq_no(ecf.get_feed_id())

        own_last_event = Event.from_cbor(function.get_event(ecf.get_feed_id(), own_last_event_sequence_number))
        last_own_message_not_reached = True
        for x in event_list:

            if own_last_event.content.content[0] == 'ratchet/contactInfo':
                if x[0][0] != 'ratchet/message':
                    last_own_message_not_reached = False
                    continue

            elif own_last_event.content.content[0] == 'ratchet/message':
                if x[0][0] != 'ratchet/message':
                    continue
            if last_own_message_not_reached:
                if x[0][1]['ciphertext'] == own_last_event.content.content[1]['ciphertext']:
                    last_own_message_not_reached = False
                    continue

                continue

            # print('print msg')
            received_message_raw = expose_message_tcp(x[0][1]['ciphertext'], bob)
            print("Received:", received_message_raw)

    else:
        print('no new messages')
Exemplo n.º 11
0
 def get_event_content(self, feed_id, seq_no):
     cbor_event = self.db_connector.get_event(feed_id, seq_no)
     event = Event.from_cbor(cbor_event)
     return event.content.content
Exemplo n.º 12
0
def test_get_kotlin_event():
    try:
        with LogCapture() as log_cap:
            ecf = EventFactory()

            kf = KotlinFunction()

            new_event = ecf.next_event('MASTER/MASTER', {})
            kf.insert_event(new_event)

            feed = EventFactory()
            feed2 = EventFactory()
            feed3 = EventFactory()

            new_event = feed.next_event('KotlinUI/MASTER', {'master_feed': ecf.get_feed_id()})
            kf.insert_event(new_event)

            new_event = feed2.next_event('KotlinUI/MASTER', {'master_feed': ecf.get_feed_id()})
            kf.insert_event(new_event)

            new_event = feed3.next_event('KotlinUI/MASTER', {'master_feed': ecf.get_feed_id()})
            kf.insert_event(new_event)

            new_event = feed.next_event('KotlinUI/username',
                                        {'newUsername': '******', 'oldUsername': '',
                                         'timestamp': 1})
            kf.insert_event(new_event)

            new_event = feed2.next_event('KotlinUI/username',
                                         {'newUsername': '******', 'oldUsername': '', 'timestamp': 2})
            kf.insert_event(new_event)

            new_event = feed3.next_event('KotlinUI/username',
                                         {'newUsername': '******', 'oldUsername': '', 'timestamp': 3})
            kf.insert_event(new_event)

            new_event = feed.next_event('KotlinUI/post',
                                        {'text': 'Hi Alice, nice to hear from you', 'username': '******',
                                         'timestamp': 11})
            kf.insert_event(new_event)

            new_event = feed2.next_event('KotlinUI/post',
                                         {'text': 'Hi Bob', 'username': '******', 'timestamp': 15})
            kf.insert_event(new_event)

            new_event = feed3.next_event('KotlinUI/post',
                                         {'text': 'Hello everyone', 'username': '******',
                                          'timestamp': 17})
            kf.insert_event(new_event)

            new_event = feed2.next_event('KotlinUI/username',
                                         {'newUsername': '******', 'oldUsername': '******', 'timestamp': 20})
            kf.insert_event(new_event)

            s = kf.get_all_kotlin_events()
            print(s)
            assert s[0][0] == 'username'
            assert s[1][0] == 'username'
            assert s[3][0] == 'post'
            p = kf.get_usernames_and_feed_id()
            print(p)
            assert p[0][0] == 'Bob'
            assert p[1][0] == 'Alice2'
            q = kf.get_all_entries_by_feed_id(feed.get_feed_id())
            print(q)
            assert q[0][3] == 1
            assert q[1][2] == 11
            m = kf.get_last_kotlin_event()
            t = Event.from_cbor(m)
            assert t.content.content[0] == 'KotlinUI/username'
            assert True
            print(log_cap)

    finally:
        try:
            if os.path.exists('cborDatabase.sqlite'):
                os.remove('cborDatabase.sqlite')
                if os.path.exists('eventDatabase.sqlite'):
                    os.remove('eventDatabase.sqlite')
                    pass
            else:
                assert False
        except PermissionError:
            print('Database is still in use')
Exemplo n.º 13
0
def test_get_current_seq_no():
    try:
        private_key = secrets.token_bytes(32)
        signing_key = SigningKey(private_key)
        public_key_feed_id1 = signing_key.verify_key.encode()

        content = Content('whateverapp/whateveraction', {
            'somekey': 'somevalue',
            'someotherkey': 2
        })
        hash_of_content = hashlib.sha256(content.get_as_cbor()).hexdigest()
        hash_of_prev = None
        meta = Meta(public_key_feed_id1, 0, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()

        connector = DatabaseConnector()
        connector.add_event(event)
        meta = Meta(public_key_feed_id1, 1, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        meta = Meta(public_key_feed_id1, 2, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        content = Content('whateverapp/whateveraction', {
            'test1': 'somevalue',
            'someotherkey': 2
        })
        meta = Meta(public_key_feed_id1, 3, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)

        private_key = secrets.token_bytes(32)
        signing_key = SigningKey(private_key)
        public_key_feed_id2 = signing_key.verify_key.encode()
        meta = Meta(public_key_feed_id2, 0, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        meta = Meta(public_key_feed_id2, 1, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        meta = Meta(public_key_feed_id2, 2, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        meta = Meta(public_key_feed_id2, 3, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        content = Content('whateverapp/whateveraction', {
            'test2': 'somevalue',
            'someotherkey': 2
        })
        meta = Meta(public_key_feed_id2, 4, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        res1 = connector.get_current_seq_no(public_key_feed_id1)
        res2 = connector.get_current_seq_no(public_key_feed_id2)
        result1 = connector.get_current_event(public_key_feed_id1)
        result2 = connector.get_current_event(public_key_feed_id2)
        print(result1)
        print(result2)
        assert res1 == 3
        assert res2 == 4
    finally:
        try:
            if os.path.exists('cborDatabase.sqlite'):
                os.remove('cborDatabase.sqlite')
                if os.path.exists('eventDatabase.sqlite'):
                    os.remove('eventDatabase.sqlite')
            else:
                assert False
        except PermissionError:
            print('Database is still in use')
def test_get_current_seq_no():
    with session_scope():
        private_key = secrets.token_bytes(32)
        signing_key = SigningKey(private_key)
        public_key_feed_id1 = signing_key.verify_key.encode()

        content = Content('whateverapp/whateveraction', {
            'somekey': 'somevalue',
            'someotherkey': 2
        })
        hash_of_content = hashlib.sha256(content.get_as_cbor()).hexdigest()
        hash_of_prev = None
        meta = Meta(public_key_feed_id1, 0, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()

        connector = DatabaseConnector()
        connector.add_event(event)
        meta = Meta(public_key_feed_id1, 1, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        meta = Meta(public_key_feed_id1, 2, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        content = Content('whateverapp/whateveraction', {
            'test1': 'somevalue',
            'someotherkey': 2
        })
        meta = Meta(public_key_feed_id1, 3, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)

        private_key = secrets.token_bytes(32)
        signing_key = SigningKey(private_key)
        public_key_feed_id2 = signing_key.verify_key.encode()
        meta = Meta(public_key_feed_id2, 0, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        meta = Meta(public_key_feed_id2, 1, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        meta = Meta(public_key_feed_id2, 2, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        meta = Meta(public_key_feed_id2, 3, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        content = Content('whateverapp/whateveraction', {
            'test2': 'somevalue',
            'someotherkey': 2
        })
        meta = Meta(public_key_feed_id2, 4, hash_of_prev, 'ed25519',
                    ('sha256', hash_of_content))
        signature = signing_key.sign(meta.get_as_cbor())._signature
        event = Event(meta, signature, content).get_as_cbor()
        connector.add_event(event)
        res1 = connector.get_current_seq_no(public_key_feed_id1)
        res2 = connector.get_current_seq_no(public_key_feed_id2)
        result1 = connector.get_current_event(public_key_feed_id1)
        result2 = connector.get_current_event(public_key_feed_id2)
        print(result1)
        print(result2)
        assert res1 == 3
        assert res2 == 4
Exemplo n.º 15
0
def start_server():  ## Bob
    print("I AM BOB")
    bob = Bob(identifier_other='Alice')
    #print("Status:", bob.x3dh_status)
    event_list = cf.get_all_saved_events(1)

    if len(event_list) > 0:
        last_event = event_list[-1]
        content, meta = last_event
        feed_id = Meta.from_cbor(meta).feed_id

    if bob.x3dh_status == 0:
        prekey_bundle = bob.x3dh_1_create_prekey_bundle()
        # TODO (identifier_other comes from bacnet): save_prekeys(prekey_bundle, identifier_other)
        send_first_Bacnet_prekey_bundle(ecf.get_feed_id(), prekey_bundle)
        exit()

    if event_list[1][0][0] == 'ratchet/connect' and bob.x3dh_status == 1:
        if bob.x3dh_status == 1:
            #print(event_list[1][0][1]['key_bundle'])
            bob.x3dh_2_complete_transaction_with_alice_keys(event_list[1][0][1]['key_bundle'])

            print("Waiting for an initial message from alice...")

            bob.x3dh_status = 2


    if content[0] == 'ratchet/message' or content[0] == 'ratchet/connect':
        if bob.x3dh_status == 2:

            if ecf.get_feed_id() != feed_id:
                own_last_event_sequence_number = function.get_current_seq_no(ecf.get_feed_id())

                own_last_event = Event.from_cbor(function.get_event(ecf.get_feed_id(), own_last_event_sequence_number))
                last_own_message_not_reached = True
                for x in event_list:

                    if own_last_event.content.content[0] == 'ratchet/contactInfo':
                        if x[0][0] != 'ratchet/message':
                            last_own_message_not_reached = False
                            continue

                    elif own_last_event.content.content[0] == 'ratchet/message':
                        if x[0][0] != 'ratchet/message':
                            continue
                    if last_own_message_not_reached:
                        if x[0][1]['ciphertext'] == own_last_event.content.content[1]['ciphertext']:
                            last_own_message_not_reached = False
                            continue

                        continue


                    #print('print msg')
                    received_message_raw = expose_message_tcp(x[0][1]['ciphertext'], bob)
                    print("Received:", received_message_raw)

            else:
                print('no new messages')

            while True:
                try:
                    msg = input('Please enter your message: ')
                    if msg == 'quit':
                        break
                    send_Bacnet_msg(encapsulate_message_tcp(bob, msg), feed_id, ecf.get_feed_id())
                except KeyboardInterrupt:
                    print('Interrupted')
                    sys.exit(0)