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)
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)
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()
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 __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 __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()
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))
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())
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])
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
def __init__(self): self.network_sender = NetworkSender()
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 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
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)