def test_store_and_retrieve(self): # first store a record with random source and target ip addresses, # and see if we can recover it. col_request = pep3_pb2.StoreRequest() col_request.id = os.urandom(16) flowrecord = col_request.records.add() flowrecord.source_ip.data = os.urandom(16) flowrecord.source_ip.state = pep3_pb2.Pseudonymizable.UNENCRYPTED_NAME flowrecord.destination_ip.data = os.urandom(16) flowrecord.destination_ip.state = \ pep3_pb2.Pseudonymizable.UNENCRYPTED_NAME flowrecord.anonymous_part.number_of_bytes = 123 flowrecord.anonymous_part.number_of_packets = 456 updates = list(self.collector.connect_to('collector').Store( iter([col_request]))) self.assertEqual(len(updates), 1) self.assertEqual(updates[0].stored_id, col_request.id) # store the same flowrecord twice, to see if that causes troubles col_request.id = os.urandom(16) updates = list(self.collector.connect_to('collector').Store( iter([col_request]))) self.assertEqual(len(updates), 1) self.assertEqual(updates[0].stored_id, col_request.id) query = pep3_pb2.SqlQuery() # manually compute storage_facility-local pseudonyms for query sf_name = b"PEP3 storage_facility" pseudonym_secrets = {} for peer_secrets in self.secrets.peers.values(): for shard, shard_secrets in peer_secrets.by_shard.items(): pseudonym_secrets[shard] \ = shard_secrets.pseudonym_component_secret s = 1 e = ed25519.scalar_unpack(common.sha256(sf_name)) for secret in pseudonym_secrets.values(): s *= pow(ed25519.scalar_unpack(secret), e, ed25519.l) s %= ed25519.l # see if the record was stored correctly by querying the # database directly. query.query = """SELECT peped_flows.p_dst_ip FROM peped_flows WHERE peped_flows.p_src_ip=:ip""" ip = query.parameters['ip'].pseudonymizable_value ip.data = (ed25519.Point.lizard( flowrecord.source_ip.data) * s).pack() ip.state = pep3_pb2.Pseudonymizable.UNENCRYPTED_PSEUDONYM row = self.sf.connect_to('database') \ .Query(query).next().rows[0] self.assertEqual(row.cells[0].pseudonymizable_value.data, (ed25519.Point.lizard(flowrecord.destination_ip.data) * s ).pack()) # manually compute researcher-local pseudonyms for query researcher_name = b"PEP3 researcher" pseudonym_secrets = {} for peer_secrets in self.secrets.peers.values(): for shard, shard_secrets in peer_secrets.by_shard.items(): pseudonym_secrets[shard] \ = shard_secrets.pseudonym_component_secret s = 1 e = ed25519.scalar_unpack(common.sha256(researcher_name)) for secret in pseudonym_secrets.values(): s *= pow(ed25519.scalar_unpack(secret), e, ed25519.l) s %= ed25519.l # now query via the researcher query.parameters['ip'].pseudonymizable_value.data \ = (ed25519.Point.lizard(flowrecord.source_ip.data) * s).pack() row = self.researcher.connect_to('researcher') \ .Query(query).next().rows[0] self.assertEqual(row.cells[0].pseudonymizable_value.data, (ed25519.Point.lizard(flowrecord.destination_ip.data) * s ).pack())