Ejemplo n.º 1
0
def main():
    log_init("m_client.log")
    args = vars(parse())
    portEnum = PortEnum
    if args['debug']:
        Debug.dbg = True
        portEnum = PortEnumDebug

    client = Client({'ip': args['pkserver'], 'port': portEnum.broker.value})
    client.populate_broker_lists()
    index = int(args['requested_index'])
    db = int(args['database'])
    requested_index, requested_db = (index, db)
    messageCreator = MessageCreator(client)
    network_sender = NetworkSender()
    record_size = client.getDBRecordSize(portEnum, network_sender)
    print(record_size)
    pir_xor = False
    if args['xor']:
        pir_xor = True
    messages = messageCreator.generate_messages(requested_index, requested_db,
                                                record_size, portEnum, pir_xor)
    print("MESSAGE CREATED")
    for db in messages:
        [network_sender.send_data(json, dest) for json, dest in messages[db]]
    print("MESSAGE SENT")
    print("POLL_INDEX RESULT:", client.poll_index(pir_xor, requested_index),
          "REQUESTED_INDEX", requested_index)
Ejemplo n.º 2
0
def test_listener():
    portEnum = PortEnumDebug
    thing = Client({'ip': '0.0.0.0', 'port': portEnum.broker.value})
    group = getGlobalSphinxParams().group.G
    dummy_key = group.generator().export()
    SecurityParameters.NUMBER_OF_REQUESTS = 3
    thing.db_list = [(0, dummy_key), (1, dummy_key), (2, dummy_key)]
    thing.mixnode_list = {
        '0.0.0.0': dummy_key,
        '0.0.0.0': dummy_key,
        '0.0.0.0': dummy_key
    }
    msgCreator = MessageCreator(thing)
    requested_index = 5
    record_size = 100
    requested_db = 2
    messages = msgCreator.generate_messages(requested_index,
                                            requested_db,
                                            record_size,
                                            portEnum,
                                            pir_xor=False)
    host = '0.0.0.0'
    port = portEnum.mix.value
    mix = MixNode(None)
    mix.process = MagicMock(return_value=(Relay_flag, None, None, None))
    listener = MixNodeListener(host, port, mix, (Lock(), Lock()), port)  #
    network_sender = NetworkSender()
    json, dest = messages[0][0]
    network_sender.send_data(json, dest)
    asyncore.loop(count=2)
    assert (len(mix.mix_pool.getContents()) == 1)
Ejemplo n.º 3
0
class DbListenerHandler(RequestHandler):
    def setData(self, dbnode, mixport, t_accepted, callback_data=None):
        super().setData(callback_data)
        self.dbnode = dbnode
        self.mixport = mixport
        self.network_sender = NetworkSender()
        self.t_accepted = t_accepted

    def handle_PIR(self, decrypted_msg, client_pk):
        time_queued = time.perf_counter() - self.t_accepted
        log_info(">>>>> TIME QUEUED: {}".format(time_queued))
        t1 = time.perf_counter()
        print("TRYING TO FETCH")
        answer = self.dbnode.fetch_answer(decrypted_msg)
        print("ANSWER:", answer)
        reply = encode(answer)
        encrypted_reply = encode(self.dbnode.encrypt(reply, client_pk))
        nymtuple = decrypted_msg['nymtuple']
        first_node = decode(nymtuple[0])
        header, delta = package_surb(getGlobalSphinxParams(), nymtuple,
                                     encrypted_reply)
        self.dbnode.get_mixnode_list()
        json_data, dest = RequestCreator().post_msg_to_mix(
            {
                'ip': first_node[1],
                'port': self.mixport
            }, {
                'header': header,
                'delta': delta
            })
        t2 = time.perf_counter()
        elapsed_time = (t2 - t1)
        log_info("TIME ELAPSED: {}".format(elapsed_time))
        self.network_sender.send_data(json_data, dest)

    def handle_read(self):
        data = super().handle_read()
        if data:
            data = pickle.loads(data)
            iv = data["iv"]
            text = data["text"]
            pk = EcPt.from_binary(data["pk"], getGlobalSphinxParams().group.G)
            tag = data["tag"]
            decrypted_msg = decode(self.dbnode.decrypt(iv, text, pk, tag))
            request_type = decrypted_msg['request_type']
            client_pk = decrypted_msg['pk'][2]
            if request_type == RequestType.get_db_size.value:
                record_size = self.dbnode.getRecordsSize()
                reply = encode(record_size)
                self.socket.sendall(reply)
            elif request_type == RequestType.push_to_db.value:
                pir_handler = threading.Thread(target=self.handle_PIR,
                                               args=(
                                                   decrypted_msg,
                                                   client_pk,
                                               ),
                                               name="PIR handler")
                pir_handler.daemon = True
                pir_handler.start()
Ejemplo n.º 4
0
 def __init__(self, myid, mixnode, client, message_pool):
     Thread.__init__(self)
     self.id = myid
     self.mixnode = mixnode
     self.network_sender = NetworkSender()
     self.request_creator = RequestCreator()
     self.client = client
     self.message_pool = message_pool
Ejemplo n.º 5
0
 def __init__(self, broker_config):
     self.private_key = None
     self.public_key = None
     self.ip = None
     self.params = getGlobalSphinxParams()
     self.network_sender = NetworkSender()
     self.broker_config = broker_config
     self.encryptor = Encryptor(self.params.group)
     self.mixnodes_list = None
     self.broker_comm = BrokerCommunicator()
     self.records = {}
     self.loadRecords()
     self.decoder = BinaryEncoderDecoder()
Ejemplo n.º 6
0
 def __init__(self, broker_config, pool_size=3):
     self.private_key = None
     self.public_key = None
     self.ip = None
     self.params = getGlobalSphinxParams()
     self.network_sender = NetworkSender()
     self.broker_config = broker_config
     self.encryptor = Encryptor(self.params.group)
     self.db_list = None
     self.broker_comm = BrokerCommunicator()
     self.client_cache = {}
     self.mix_pool = MixPool(pool_size)
     self.client_backlog = set()
Ejemplo n.º 7
0
class MixListenerHandler(RequestHandler):
    def setData(self, mixnode, locks, mixport, callback_data=None):
        super().setData(callback_data)
        self.mixnode = mixnode
        self.network_sender = NetworkSender()
        self.backlog_lock, self.pool_lock  = locks
        self.mixport = mixport

    def handle_read(self):
        data = super().handle_read()
        if data:
            data = pickle.loads(data)
            if data['type'] == RequestType.push_to_mix.value:
                start = time.time()
                operation = ''
                data = decode(data['payload'])
                header = data['header']
                delta = data['delta']
                result = self.mixnode.process(header, delta)
                if result[0] == Relay_flag:
                    flag, addr, header, delta = result
                    json_data, dest = RequestCreator().post_msg_to_mix(
                        {'ip': addr, 'port': self.mixport},
                        {'header': header, 'delta': delta}
                    )
                    with self.pool_lock:
                        self.mixnode.pool_item((json_data, dest))
                    operation = '[RELAY_FLAG] pool'
                elif result[0] == Dest_flag:
                    flag, msg, dest, _ = result
                    json_data, dest = RequestCreator().post_msg_to_db(dest, msg)
                    self.network_sender.send_data(json_data, dest)
                    operation = '[DEST_FLAG] send'
                elif result[0] == Surb_flag:
                    flag, dest, myid, delta = result
                    msg = {'myid': myid, 'delta': delta}
                    print("CACHING")
                    self.mixnode.client_cache.setdefault(myid, []).append(msg)
                    operation = '[SURB_FLAG] cache'
                end = time.time()
                timestamp = datetime.fromtimestamp(
                    end - start).strftime('%M:%S')
                logger.log_info(
                    '[TIME] MIX LISTENER {} TOOK {}'.format(operation, timestamp))
            elif data['type'] == RequestType.client_poll.value:
                client_id = data['id']
                with self.backlog_lock:
                    self.mixnode.client_backlog.add((client_id, self.socket))
Ejemplo n.º 8
0
class BrokerCommunicator:
    def __init__(self):
        self.network_sender = NetworkSender()

    def getMixNodeList(self, source):
        request_creator = RequestCreator()
        data_string, serialized_destination = request_creator.get_all_mixnode_request(
            source)
        response = self.network_sender.send_data_wait(data_string,
                                                      serialized_destination)
        return json.loads(response.decode())

    def getDBList(self, source):
        request_creator = RequestCreator()
        data_string, serialized_destination = request_creator.get_all_db_request(
            source)
        response = self.network_sender.send_data_wait(data_string,
                                                      serialized_destination)
        return json.loads(response.decode())
Ejemplo n.º 9
0
class Worker(Thread):
    def __init__(self, myid, mixnode, client, message_pool):
        Thread.__init__(self)
        self.id = myid
        self.mixnode = mixnode
        self.network_sender = NetworkSender()
        self.request_creator = RequestCreator()
        self.client = client
        self.message_pool = message_pool

    def run(self):
        json_data, destination = self.request_creator.poll_mixnode(
            self.id, self.mixnode)
        response = self.network_sender.send_data_wait(json_data, destination)
        if response:
            response = decode(response)
            id = response['id']
            response = response['response']
            for entry in response:
                msg = entry['delta']
                recoveredMessage = self.client.recoverMessage(
                    msg, entry['myid'])
                self.message_pool[id] = (recoveredMessage[0],
                                         recoveredMessage[1])
Ejemplo n.º 10
0
class DbNode():
    def _get_mixnode_list(self):
        def unhexlify_values(a_dict):
            for x in a_dict.keys():
                a_dict[x] = unhexlify(a_dict[x])
            return a_dict

        source = {
            'ip': self.broker_config['pkserver'],
            'port': self.broker_config['port']
        }
        mixnodes_dict = self.broker_comm.getMixNodeList({
            'ip': source['ip'],
            'port': source['port']
        })
        mixnodes_dict = unhexlify_values(mixnodes_dict)
        return mixnodes_dict

    def __init__(self, broker_config):
        self.private_key = None
        self.public_key = None
        self.ip = None
        self.params = getGlobalSphinxParams()
        self.network_sender = NetworkSender()
        self.broker_config = broker_config
        self.encryptor = Encryptor(self.params.group)
        self.mixnodes_list = None
        self.broker_comm = BrokerCommunicator()
        self.records = {}
        self.loadRecords()
        self.decoder = BinaryEncoderDecoder()

    def loadRecords(self):
        path = self.broker_config['database']
        f = open(path, 'r')
        self.records = json.load(f)

    def get_mixnode_list(self):
        if self.mixnodes_list is None:
            self.mixnodes_list = self._get_mixnode_list()
        return self.mixnodes_list

    def getIp(self):
        if self.ip is None:
            self.ip = getPublicIp()
        return self.ip

    def decrypt(self, iv, text, pk, tag):
        msg = self.encryptor.decrypt_aes_gcm((pk, iv, text, tag),
                                             self.private_key[1])
        return msg

    def encrypt(self, msg, client_key):
        g_x, iv, ciphertext, tag = self.encryptor.encrypt_aes_gcm(
            msg, client_key, os.urandom(16))
        encrypted_reply = {'pk': g_x, 'iv': iv, 'text': ciphertext, 'tag': tag}
        return encrypted_reply

    def xor_records(self, mlist):
        records = self.getRecords()
        for row in mlist:
            message = ''
            for i in range(0, len(row)):
                if row[i] == 1:
                    if message == '':
                        message = records[i]
                    else:
                        message = pir_executor.stringXorer(message, records[i])
        return message

    def getRecords(self):
        return self.records

    def getRecordsSize(self):
        length = len(self.records['collection'])
        print(length)
        return length

    def fetch_answer(self, msg):
        print("here")
        try:
            db_cache = self.getRecords()['collection']
            pir_xor = msg['pir_xor']
            if not pir_xor:
                index = msg['index']
                return db_cache[index]
            else:
                pir_executor = PIRExecutor()
                vector = msg['index']
                print("Decoding")
                vector = self.decoder.decode_binary(vector, len(db_cache))
                print("Decoded")
                message = ''
                for i, val in enumerate(vector):
                    if val == 1:
                        if message == '':
                            message = db_cache[i]
                        else:
                            message = pir_executor.stringXorer(
                                message, db_cache[i])
                return message
        except IndexError:
            return b'No such index in the database.'

    def publish_key(self):
        def prepare_sending_pk(public_key, server_config):
            key_server_ip = server_config['pkserver']
            port = server_config['port']
            try:
                response = os.system("ping -c 1 " + key_server_ip)
                if response != 0:
                    raise ValueError(
                        "Server: {} cannot be reached. The key was not published"
                        .format(ip))
                else:
                    request_creator = RequestCreator()
                    json_data, destination = request_creator.post_db_key_request(
                        {
                            'ip': key_server_ip,
                            'port': port
                        }, {
                            'id': public_key[0],
                            'pk': public_key[2]
                        })
                    return (json_data, destination)
            except Exception as error:
                print("Unexpected error: {}".format(error))
                return None
            return None

        self.public_key, self.private_key = self.encryptor.keyGenerate(
            self.getIp())
        json_data, destination = prepare_sending_pk(self.public_key,
                                                    self.broker_config)
        #publish key
        response = self.network_sender.send_data(json_data, destination)
        return response
Ejemplo n.º 11
0
 def __init__(self):
     self.network_sender = NetworkSender()
Ejemplo n.º 12
0
 def setData(self, dbnode, mixport, t_accepted, callback_data=None):
     super().setData(callback_data)
     self.dbnode = dbnode
     self.mixport = mixport
     self.network_sender = NetworkSender()
     self.t_accepted = t_accepted
Ejemplo n.º 13
0
 def setData(self, mixnode, locks, mixport, callback_data=None):
     super().setData(callback_data)
     self.mixnode = mixnode
     self.network_sender = NetworkSender()
     self.backlog_lock, self.pool_lock  = locks
     self.mixport = mixport
Ejemplo n.º 14
0
class MixNode():
    def __init__(self, broker_config, pool_size=3):
        self.private_key = None
        self.public_key = None
        self.ip = None
        self.params = getGlobalSphinxParams()
        self.network_sender = NetworkSender()
        self.broker_config = broker_config
        self.encryptor = Encryptor(self.params.group)
        self.db_list = None
        self.broker_comm = BrokerCommunicator()
        self.client_cache = {}
        self.mix_pool = MixPool(pool_size)
        self.client_backlog = set()

    def handlePool(self, pool_lock):
        while (1):
            with pool_lock:
                # print("POOL SIZE: {}".format(len(self.mix_pool.getContents())))
                items_to_send = self.mix_pool.getSelection()
            for entry in items_to_send:
                json_data, destination = entry
                if Debug.dbg:
                    destination['ip'] = '0.0.0.0'
                print("SENDING")
                self.network_sender.send_data(json_data, destination)
            time.sleep(0.05)

    def handleCache(self, backlog_lock):
        while 1:
            toRemove = []
            with backlog_lock:
                # print('Cache size: {}'.format(len(self.client_cache)))
                for entry in self.client_backlog:
                    client_id, socket = entry
                    if client_id in self.client_cache:
                        toRemove.append(entry)
                        start = time.time()
                        operation = ''
                        response = self.client_cache.get(client_id)
                        response = encode({
                            "id": client_id,
                            "response": response
                        })
                        socket.sendall(response)
                        self.client_cache.pop(client_id)
                        operation = '[CLIENT_POLL] send'
                        end = time.time()
                        timestamp = datetime.fromtimestamp(
                            end - start).strftime('%M:%S:%f')
                        logger.log_info(
                            '[TIME] MIX LISTENER {} TOOK {}'.format(
                                operation, timestamp))
                for entry in toRemove:
                    self.client_backlog.remove(entry)
            time.sleep(0.05)

    def pool_item(self, item):
        self.mix_pool.addInPool(item)

    def getDbList(self):
        def unhexlify_values(a_dict):
            for x in a_dict.keys():
                a_dict[x] = unhexlify(a_dict[x])
            return a_dict

        def _get_db_list(source):
            dbs_dict_raw = self.broker_comm.getDBList({
                'ip': source['ip'],
                'port': source['port']
            })
            dbs_dict_raw = unhexlify_values(dbs_dict_raw)
            dbs_dict = {}
            for index, (key, value) in enumerate(dbs_dict_raw.items()):
                dbs_dict['DB{}'.format(index)] = (key, value)
            return dbs_dict

        if self.db_list == None:
            source = {
                'ip': self.broker_config['pkserver'],
                'port': self.broker_config['port']
            }
            self.db_list = _get_db_list(source)
        return self.db_list

    def publish_key(self):
        def prepare_sending_pk(public_key, server_config):
            key_server_ip = server_config['pkserver']
            port = server_config['port']
            try:
                response = os.system("ping -c 1 " + key_server_ip)
                if response != 0:
                    raise ValueError(
                        "Server: {} cannot be reached. The key was not published"
                        .format(self.ip))
                else:
                    request_creator = RequestCreator()
                    json_data, destination = request_creator.post_mix_key_request(
                        {
                            'ip': key_server_ip,
                            'port': port
                        }, {
                            'id': public_key[0],
                            'pk': public_key[2]
                        })
                    return (json_data, destination)
            except Exception as error:
                print("Unexpected error: {}".format(error))
                return None
            return None

        self.public_key, self.private_key = self.encryptor.keyGenerate(
            self.getIp())
        json_data, destination = prepare_sending_pk(self.public_key,
                                                    self.broker_config)
        # publish key
        response = self.network_sender.send_data(json_data, destination)
        return response

    def getIp(self):
        if self.ip is None:
            self.ip = getPublicIp()
        return self.ip

    def process(self, header, delta, cb=None):
        private_key = self.private_key
        ret = sphinx_process(self.params, private_key.x, header, delta)
        (tag, info, (header, delta)) = ret
        routing = PFdecode(self.params, info)
        if routing[0] == Relay_flag:
            flag, addr = routing
            return (Relay_flag, addr, header, delta)
        elif routing[0] == Dest_flag:
            dest, msg = receive_forward(self.params, delta)
            return (Dest_flag, msg, dest, None)
        elif routing[0] == Surb_flag:
            flag, dest, myid = routing
            return (flag, dest, myid, delta)