def make_alice_control(drone_alice: Alice, teacher_node: Ursula): alice_control = Flask("alice-control") teacher_node.verify_node(drone_alice.network_middleware) drone_alice.remember_node(teacher_node) drone_alice.start_learning_loop(now=True) @alice_control.route("/create_policy", methods=['PUT']) def create_policy(): """ Character control endpoint for creating a policy and making arrangements with Ursulas. This is an unfinished API endpoint. You are probably looking for grant. """ # TODO: Needs input cleansing and validation # TODO: Provide more informative errors try: request_data = json.loads(request.data) bob_pubkey = bytes.fromhex(request_data['bob_encrypting_key']) label = b64decode(request_data['label']) # TODO: Do we change this to something like "threshold" m, n = request_data['m'], request_data['n'] federated_only = True # const for now bob = Bob.from_public_keys( { DecryptingPower: bob_pubkey, SigningPower: None }, federated_only=True) except (KeyError, JSONDecodeError) as e: return Response(str(e), status=400) new_policy = drone_alice.create_policy(bob, label, m, n, federated=federated_only) # TODO: Serialize the policy return Response('Policy created!', status=200) @alice_control.route("/grant", methods=['PUT']) def grant(): """ Character control endpoint for policy granting. """ # TODO: Needs input cleansing and validation # TODO: Provide more informative errors try: request_data = json.loads(request.data) bob_pubkey = bytes.fromhex(request_data['bob_encrypting_key']) label = b64decode(request_data['label']) # TODO: Do we change this to something like "threshold" m, n = request_data['m'], request_data['n'] expiration_time = maya.MayaDT.from_iso8601( request_data['expiration_time']) federated_only = True # const for now bob = Bob.from_public_keys( { DecryptingPower: bob_pubkey, SigningPower: None }, federated_only=True) except (KeyError, JSONDecodeError) as e: return Response(str(e), status=400) new_policy = drone_alice.grant(bob, label, m=m, n=n, expiration=expiration_time) # TODO: Serialize the policy response_data = { 'result': { 'treasure_map': b64encode(bytes(new_policy.treasure_map)).decode(), } } return Response(json.dumps(response_data), status=200) return alice_control
BOB_B = Bob(known_nodes=[ursula], domains={TEMPORARY_DOMAIN}, network_middleware=RestMiddleware(), federated_only=True, start_learning_now=True, learn_on_same_thread=True) BOB_D = Bob(known_nodes=[ursula], domains={TEMPORARY_DOMAIN}, network_middleware=RestMiddleware(), federated_only=True, start_learning_now=True, learn_on_same_thread=True) ALICE.start_learning_loop(now=True) ########################################### # Creating our policies for data sharing # ########################################### print( "Alice, our patient, shares her data with researchers A, B, and D. She opts not to share with C because their trial is not relevant to her." ) print("Creating policy for trial A") policy_A = ALICE.grant(BOB_A, label_A, m=m, n=n, expiration=policy_end_datetime)
SHARED_CRUFTSPACE = "{}/nucypher/examples/examples-runtime-cruft".format(os.path.dirname(os.path.abspath(__file__))) CRUFTSPACE = "{}/drm".format(SHARED_CRUFTSPACE) CERTIFICATE_DIR = "{}/certs".format(CRUFTSPACE) shutil.rmtree(CRUFTSPACE, ignore_errors=True) os.mkdir(CRUFTSPACE) os.mkdir(CERTIFICATE_DIR) URSULA.save_certificate_to_disk(CERTIFICATE_DIR) print("DDRM: Instantiating the stream author") author = Author(network_middleware=RestMiddleware(), known_nodes=(URSULA,), federated_only=True, known_certificates_dir=CERTIFICATE_DIR, ) print("DDRM: Author instantiated {}".format(author)) author.start_learning_loop(now=True) print("DDRM: Instantiating raw unprotected stream to keep in secret") raw_stream = RawStream(author) print("DDRM: Raw unprotected stream instantiated {}".format(raw_stream)) print("DDRM: Encyphering the stream for publishing") protected_stream = PublicEdekProtectedStream(raw_stream) print("DDRM: Stream encrypted and published {}".format(protected_stream)) print("DDRM: Instantiating the Subscriber") subscriber = Subscriber(known_nodes=(URSULA,), federated_only=True, known_certificates_dir=CERTIFICATE_DIR) print("DDRM: Subscriber instantiated {}".format(subscriber)) print("DDRM: grant access Subscriber to the stream (its episodes)") protected_stream.grant_access_to_episodes(subscriber) print("DDRM: Subscriber was given access to the episodes") print("DDRM: Instantiate subscriber's player and connect to the stream")
##################################################### # Alice can get the public key even before creating the policy. # From this moment on, any Data Source like Enrico that knows the public key # can encrypt data originally intended for Alice, but that can be shared with # any Bob that Alice grants access. # To share this key, Alice stores it on-chain policy_pubkey = alice.get_policy_encrypting_key_from_label(health_label) # Alice stores the policy public key on chain w3.eth.defaultAccount = alice_eth_address tx_hash = alice_proxy_account.functions.setData( health_label_key, policy_pubkey.to_bytes()).transact() w3.eth.waitForTransactionReceipt(tx_hash) alice.start_learning_loop(now=True) # Here are our Policy details. policy_end_datetime = maya.now() + datetime.timedelta(days=5) m, n = 2, 3 # Alice uses Bob's Decentralized ID on-chain to collects relevant data and create a Bob profile bob_nucypher_decrypting_pub_key_as_seen_by_alice = bob_proxy_account.functions.getData( nucypher_decrypting_key).call() bob_nucypher_signing_pub_key_as_seen_by_alice = bob_proxy_account.functions.getData( nucypher_signing_key).call() bob_as_seen_by_alice = Bob.from_public_keys( powers_and_material={ DecryptingPower: bob_nucypher_decrypting_pub_key_as_seen_by_alice, SigningPower: bob_nucypher_signing_pub_key_as_seen_by_alice })
class Client(object): URSULA_SEEDNODE_URI = "" def __init__(self, ursula_url): self.URSULA_SEEDNODE_URI = ursula_url # todo : customise ipfs host self.ipfs = ipfsapi.connect("https://ipfs.infura.io", 5001) random_name = fake.name() self.label = random_name.encode() self.m = 2 self.n = 3 def node_info(self): return self.ipfs.id() def generate_recipient_keys(self): enc_privkey = UmbralPrivateKey.gen_key() sig_privkey = UmbralPrivateKey.gen_key() recipient_privkeys = { 'enc': enc_privkey.to_bytes().hex(), 'sig': sig_privkey.to_bytes().hex(), } enc_pubkey = enc_privkey.get_pubkey() sig_pubkey = sig_privkey.get_pubkey() recipient_pubkeys = { 'enc': enc_pubkey.to_bytes().hex(), 'sig': sig_pubkey.to_bytes().hex() } return recipient_privkeys, recipient_pubkeys def generate_owner_policy_public_key(self, max_days): self.ursula = Ursula.from_seed_and_stake_info( seed_uri=self.URSULA_SEEDNODE_URI, federated_only=True, minimum_stake=0) policy_end_datetime = maya.now() + datetime.timedelta(days=max_days) self.ALICE = Alice(network_middleware=RestMiddleware(), known_nodes=[self.ursula], learn_on_same_thread=True, federated_only=True) policy_pubkey = self.ALICE.get_policy_pubkey_from_label(self.label) return policy_pubkey def uploadFile(self, filename, policy_pubkey): data_source = Enrico(policy_encrypting_key=policy_pubkey) data_source_public_key = bytes(data_source.stamp) file = open(filename, "r").read() encoded = base64.b64encode(file.encode()) encrypt_message, _signature = data_source.encrypt_message(encoded) kit_bytes = encrypt_message.to_bytes() try: os.mkdir("./tmp") except Exception as e: logging.info("temp folder exist") temp = open('./tmp/' + filename, 'wb') temp.write(kit_bytes) temp.close() res = self.ipfs.add('./tmp/' + filename) receipt_info = { "data_source_public_key": data_source_public_key.hex(), "hash_key": res['Hash'] } return receipt_info def authorize(self, recipient_pubkeys, max_days=5): powers_and_material = { DecryptingPower: UmbralPublicKey.from_bytes(bytes.fromhex( recipient_pubkeys["enc"])), SigningPower: UmbralPublicKey.from_bytes(bytes.fromhex(recipient_pubkeys["sig"])) } recipient = Bob.from_public_keys( powers_and_material=powers_and_material, federated_only=True) policy_end_datetime = maya.now() + datetime.timedelta(days=max_days) m, n = self.m, self.n self.ALICE.start_learning_loop(now=True) policy = self.ALICE.grant(recipient, self.label, m=m, n=n, expiration=policy_end_datetime) alices_pubkey = bytes(self.ALICE.stamp) policy_info = { "policy_pubkey": policy.public_key.to_bytes().hex(), "alice_sig_pubkey": alices_pubkey, "label": self.label.decode("utf-8") } return policy_info def downloadFile(self, downloadFilename, recipient_privkeys, receipt, policy_info): hash = receipt['hash_key'] input = self.ipfs.cat(hash) ursula = Ursula.from_seed_and_stake_info( seed_uri=self.URSULA_SEEDNODE_URI, federated_only=True, minimum_stake=0) bob_enc_keypair = DecryptingKeypair( private_key=UmbralPrivateKey.from_bytes( bytes.fromhex(recipient_privkeys["enc"]))) bob_sig_keypair = SigningKeypair( private_key=UmbralPrivateKey.from_bytes( bytes.fromhex(recipient_privkeys["sig"]))) enc_power = DecryptingPower(keypair=bob_enc_keypair) sig_power = SigningPower(keypair=bob_sig_keypair) power_ups = [enc_power, sig_power] authorizedRecipient = Bob( is_me=True, federated_only=True, crypto_power_ups=power_ups, start_learning_now=True, abort_on_learning_error=True, known_nodes=[ursula], save_metadata=False, network_middleware=RestMiddleware(), ) policy_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_info["policy_pubkey"])) enrico_as_understood = Enrico.from_public_keys( { SigningPower: UmbralPublicKey.from_bytes( bytes.fromhex(receipt['data_source_public_key'])) }, #{SigningPower: data_source_public_key}, policy_encrypting_key=policy_pubkey) alice_pubkey_restored = UmbralPublicKey.from_bytes( (policy_info['alice_sig_pubkey'])) authorizedRecipient.join_policy(policy_info['label'].encode(), alice_pubkey_restored) kit = UmbralMessageKit.from_bytes(input) delivered_cleartexts = authorizedRecipient.retrieve( message_kit=kit, data_source=enrico_as_understood, alice_verifying_key=alice_pubkey_restored, label=(policy_info['label'].encode())) #delivered_cleartexts = authorizedRecipient.retrieve(message_kit=kit,data_source=data_source,alice_verifying_key=alice_pubkey_restored, label=(policy_info['label'].encode()) ) data = base64.b64decode(delivered_cleartexts[0]) output = open('./' + downloadFilename, 'wb') output.write(data) output.close()