def _get_or_create_alice_config(click_config, dev, network, eth_node, provider_uri, config_file, discovery_port, pay_with, registry_filepath): if dev: alice_config = AliceConfiguration( dev_mode=True, network_middleware=click_config.middleware, domains={network}, provider_process=eth_node, provider_uri=provider_uri, federated_only=True) else: try: alice_config = AliceConfiguration.from_configuration_file( dev_mode=False, filepath=config_file, domains={network} if network else None, network_middleware=click_config.middleware, rest_port=discovery_port, checksum_address=pay_with, provider_process=eth_node, provider_uri=provider_uri, registry_filepath=registry_filepath) except FileNotFoundError: return actions.handle_missing_configuration_file( character_config_class=AliceConfiguration, config_file=config_file) return alice_config
def create_config(self, emitter, config_file): if self.dev: # Can be None as well, meaning it is unset - no error in this case if self.federated_only is False: raise click.BadOptionUsage( option_name="--federated-only", message=click.style( "--federated-only cannot be explicitly set to False when --dev is set", fg="red")) return AliceConfiguration(emitter=emitter, dev_mode=True, network_middleware=self.middleware, domain=TEMPORARY_DOMAIN, eth_provider_uri=self.eth_provider_uri, signer_uri=self.signer_uri, gas_strategy=self.gas_strategy, max_gas_price=self.max_gas_price, federated_only=True, lonely=self.lonely, payment_method=self.payment_method, payment_provider=self.payment_provider, payment_network=self.payment_network) else: if not config_file: config_file = select_config_file( emitter=emitter, checksum_address=self.pay_with, config_class=AliceConfiguration) try: return AliceConfiguration.from_configuration_file( emitter=emitter, dev_mode=False, network_middleware=self.middleware, domain=self.domain, eth_provider_uri=self.eth_provider_uri, signer_uri=self.signer_uri, gas_strategy=self.gas_strategy, max_gas_price=self.max_gas_price, filepath=config_file, rest_port=self.discovery_port, checksum_address=self.pay_with, registry_filepath=self.registry_filepath, lonely=self.lonely, payment_method=self.payment_method, payment_provider=self.payment_provider, payment_network=self.payment_network) except FileNotFoundError: return handle_missing_configuration_file( character_config_class=AliceConfiguration, config_file=config_file)
def createPolicy(): print('data') print(request.data.decode('utf-8')) print('data\n\n') json_data = json.loads(request.data.decode('utf-8')) bobName = json_data['bob'] label = json_data['label'] aliceFile = json_data['alice'] password = json_data['password'] label = label.encode() # Generating Alice alice_config = AliceConfiguration.from_configuration_file( filepath=aliceFile, known_nodes={ursula}, start_learning_now=False, ) print(alice_config) alice_config.attach_keyring() alice_config.keyring.unlock(password=password) alicia = alice_config(domains={'TEMPORARY_DOMAIN'}) alicia.start_learning_loop(now=True) # Generating Bob bobFilePath = os.path.join(os.getcwd(), 'bob/' + bobName + '.json') doctor_pubkeys = _get_keys(bobFilePath, UmbralPublicKey) powers_and_material = { DecryptingPower: doctor_pubkeys['enc'], SigningPower: doctor_pubkeys['sig'] } print (powers_and_material) doctor_strange = Bob.from_public_keys(powers_and_material=powers_and_material, federated_only=True) policy_end_datetime = maya.now() + datetime.timedelta(days=10) # Generate Policy policy = alicia.grant(bob=doctor_strange, label=label, m=1, n=1, expiration=policy_end_datetime) print (policy.public_key.to_bytes().hex()) data = { 'done' : True } return jsonify(data)
def mario_box_cli(plaintext_dir, alice_config, label, outfile): # Derive Policy Encrypting Key alice_configuration = AliceConfiguration.from_configuration_file( filepath=alice_config) alice = make_cli_character(character_config=alice_configuration) alice_signing_key = alice.public_keys(SigningPower) policy_encrypting_key = alice.get_policy_encrypting_key_from_label( label=label.encode()) policy_encrypting_key_hex = bytes(policy_encrypting_key).hex() output = list() paths = list(plaintext_dir.iterdir()) click.secho( f"Encrypting {len(paths)} files for policy {policy_encrypting_key_hex}", fg='blue') with click.progressbar(paths) as bar: for path in bar: filepath = Path(plaintext_dir, path) with open(filepath, 'rb') as file: plaintext = file.read() encoded_plaintext = base64.b64encode(plaintext) enrico = Enrico(policy_encrypting_key=policy_encrypting_key) message_kit = enrico.encrypt_message( plaintext=encoded_plaintext) base64_message_kit = base64.b64encode( bytes(message_kit)).decode() # Collect Bob Retrieve JSON Requests retrieve_payload = { 'label': label, 'policy-encrypting-key': policy_encrypting_key_hex, 'alice-verifying-key': bytes(alice_signing_key).hex(), 'message-kit': base64_message_kit } output.append(retrieve_payload) if not outfile: outfile = f'{policy_encrypting_key_hex}.json' with open(outfile, 'w') as file: file.write(json.dumps(output, indent=2)) click.secho(f"Successfully wrote output to {outfile}", fg='green')
def act_as_alice(self, name, password): dirname = "accounts/" + name + "/" congifloc = dirname + "alice.config" alice_config = AliceConfiguration( config_root=os.path.join(dirname), is_me=True, known_nodes={self.ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) cfg = alice_config.from_configuration_file(congifloc) cfg.keyring.unlock(password) alice = cfg.produce() # alice.start_learning_loop(now=True) return alice
def _get_alice(self): # Gets an Alice instance #print('Getting an Alice') try: # If we had an existing Alicia in disk, let's get it from there alice_config_file = os.path.join(self.TEMP_ALICE_DIR, "config_root", "alice.config") new_alice_config = AliceConfiguration.from_configuration_file( filepath=alice_config_file, known_nodes=[self.ursula], network_middleware=RestMiddleware(), start_learning_now=False, save_metadata=False, ) #new_alice_config.keyring.unlock(password=self.passphrase) alicia = new_alice_config.produce() except: # If anything fails, let's create Alicia from scratch # Remove previous demo files and create new ones #print("Creating ALICE") shutil.rmtree(self.TEMP_ALICE_DIR, ignore_errors=True) os.mkdir(self.TEMP_ALICE_DIR) os.mkdir(self.TEMP_ALICE_URSULA_DIR) alice_config = AliceConfiguration( config_root=os.path.join(self.TEMP_ALICE_DIR, "config_root"), is_me=True, known_nodes=[self.ursula], start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) alice_config.initialize(password=self.passphrase) alice_config.keyring.unlock(password=self.passphrase) alicia = alice_config.produce() # We will save Alicia's config to a file for later use alice_config_file = alice_config.to_configuration_file() # Let's get to learn about the NuCypher network alicia.start_learning_loop(now=True) return alicia
def create_config(self, emitter, config_file): if self.dev: # Can be None as well, meaning it is unset - no error in this case if self.federated_only is False: raise click.BadOptionUsage( option_name="--federated-only", message= "--federated-only cannot be explicitly set to False when --dev is set" ) return AliceConfiguration(emitter=emitter, dev_mode=True, network_middleware=self.middleware, domains={TEMPORARY_DOMAIN}, provider_process=self.eth_node, provider_uri=self.provider_uri, signer_uri=self.signer_uri, gas_strategy=self.gas_strategy, federated_only=True) else: try: return AliceConfiguration.from_configuration_file( emitter=emitter, dev_mode=False, network_middleware=self.middleware, domains=self.domains, provider_process=self.eth_node, provider_uri=self.provider_uri, signer_uri=self.signer_uri, gas_strategy=self.gas_strategy, filepath=config_file, rest_port=self.discovery_port, checksum_address=self.pay_with, registry_filepath=self.registry_filepath) except FileNotFoundError: return actions.handle_missing_configuration_file( character_config_class=AliceConfiguration, config_file=config_file)
def get_alice(): ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI, federated_only=True, minimum_stake=0) # A new Alice is restored from the configuration file new_alice_config = AliceConfiguration.from_configuration_file( filepath=os.path.join(TEMP_ALICE_DIR, 'alice.config.json'), domains={TEMPORARY_DOMAIN}, known_nodes={ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) # Alice unlocks her restored keyring from disk new_alice_config.attach_keyring() new_alice_config.keyring.unlock(password=passphrase) new_alice = new_alice_config() new_alice.start_learning_loop(now=True) return new_alice
def alice( click_config, action, # Mode dev, force, dry_run, # Network teacher_uri, min_stake, federated_only, network, discovery_port, controller_port, # Filesystem config_root, config_file, # Blockchain pay_with, provider_uri, geth, sync, poa, no_registry, registry_filepath, # Alice bob_encrypting_key, bob_verifying_key, label, m, n, value, rate, duration, expiration, message_kit): # # Validate # if federated_only and geth: raise click.BadOptionUsage( option_name="--geth", message="Federated only cannot be used with the --geth flag") # Banner click.clear() if not click_config.json_ipc and not click_config.quiet: click.secho(ALICE_BANNER) # # Managed Ethereum Client # ETH_NODE = NO_BLOCKCHAIN_CONNECTION if geth: ETH_NODE = actions.get_provider_process() provider_uri = ETH_NODE.provider_uri(scheme='file') # # Eager Actions (No Authentication Required) # if action == 'init': """Create a brand-new persistent Alice""" if dev: raise click.BadArgumentUsage( "Cannot create a persistent development character") if not config_root: # Flag config_root = click_config.config_file # Envvar new_alice_config = AliceConfiguration.generate( password=click_config.get_password(confirm=True), config_root=config_root, checksum_address=pay_with, rest_host="localhost", domains={network} if network else None, federated_only=federated_only, download_registry=no_registry, registry_filepath=registry_filepath, provider_process=ETH_NODE, poa=poa, provider_uri=provider_uri, m=m, n=n, duration=duration, rate=rate) painting.paint_new_installation_help( new_configuration=new_alice_config, config_root=config_root, config_file=config_file) return # Exit elif action == "view": """Paint an existing configuration to the console""" configuration_file_location = config_file or AliceConfiguration.DEFAULT_CONFIG_FILE_LOCATION response = AliceConfiguration._read_configuration_file( filepath=configuration_file_location) click_config.emit(response) return # Exit # # Make Alice # if dev: alice_config = AliceConfiguration( dev_mode=True, network_middleware=click_config.middleware, domains={network}, provider_process=ETH_NODE, provider_uri=provider_uri, federated_only=True) else: try: alice_config = AliceConfiguration.from_configuration_file( filepath=config_file, domains={network} if network else None, network_middleware=click_config.middleware, rest_port=discovery_port, checksum_address=pay_with, provider_process=ETH_NODE, provider_uri=provider_uri) except FileNotFoundError: return actions.handle_missing_configuration_file( character_config_class=AliceConfiguration, config_file=config_file) ALICE = actions.make_cli_character(character_config=alice_config, click_config=click_config, dev=dev, teacher_uri=teacher_uri, min_stake=min_stake, sync=sync) # # Admin Actions # if action == "run": """Start Alice Web Controller""" ALICE.controller.emitter( message=f"Alice Verifying Key {bytes(ALICE.stamp).hex()}", color="green", bold=True) controller = ALICE.make_web_controller( crash_on_error=click_config.debug) ALICE.log.info('Starting Alice Web Controller') return controller.start(http_port=controller_port or alice_config.controller_port, dry_run=dry_run) elif action == "destroy": """Delete all configuration files from the disk""" if dev: message = "'nucypher alice destroy' cannot be used in --dev mode" raise click.BadOptionUsage(option_name='--dev', message=message) return actions.destroy_configuration(character_config=alice_config, force=force) # # Alice API # elif action == "public-keys": response = ALICE.controller.public_keys() return response elif action == "derive-policy-pubkey": # Validate if not label: raise click.BadOptionUsage( option_name='label', message= "--label is required for deriving a policy encrypting key.") # Request return ALICE.controller.derive_policy_encrypting_key(label=label) elif action == "grant": # Validate if not all((bob_verifying_key, bob_encrypting_key, label)): raise click.BadArgumentUsage( message= "--bob-verifying-key, --bob-encrypting-key, and --label are " "required options to grant (optionally --m, --n, and --expiration)." ) # Request grant_request = { 'bob_encrypting_key': bob_encrypting_key, 'bob_verifying_key': bob_verifying_key, 'label': label, 'm': m, 'n': n, 'expiration': expiration, } if not ALICE.federated_only: grant_request.update({'value': value}) return ALICE.controller.grant(request=grant_request) elif action == "revoke": # Validate if not label and bob_verifying_key: raise click.BadArgumentUsage( message= f"--label and --bob-verifying-key are required options for revoke." ) # Request revoke_request = { 'label': label, 'bob_verifying_key': bob_verifying_key } return ALICE.controller.revoke(request=revoke_request) elif action == "decrypt": # Validate if not all((label, message_kit)): input_specification, output_specification = ALICE.controller.get_specifications( interface_name=action) required_fields = ', '.join(input_specification) raise click.BadArgumentUsage( f'{required_fields} are required flags to decrypt') # Request request_data = {'label': label, 'message_kit': message_kit} response = ALICE.controller.decrypt(request=request_data) return response else: raise click.BadArgumentUsage(f"No such argument {action}")
def __init__(self, ursula_url, dir_name, passphrase, ipfs_addr='', arweave_wallet_file_path='', federated_only=True, signer_uri='', checksum_address=None, client_password=None, provider_uri='', domain=TEMPORARY_DOMAIN): """ Args: ursula_url (str): ursula url e.g. localhost:11500 dir_name (str): dir_name where account files will be stored in tmp directory passphrase (str): passphrase for account ipfs_addr (str): ipfs addr (required only if you want to store data in ipfs) arweave_wallet_file_path (str): arweave wallet file path (required only if you want to store data in arweave) federated_only (bool): Whether federated mode should be used signer_uri (str): signer uri for ethereum transaction https://docs.nucypher.com/en/latest/guides/ethereum_node.html#external-transaction-signing checksum_address (str): Ethereum address client_password (str): Password for ethereum keystore. Required only if signer_uri is keystore://{path} provider_uri (str): geth or infura https uri domain (str): nucypher network name e.g. lynx for nucypher testnet and mainnet for nucypher mainnet """ self.__client_password = client_password self.federated_only = federated_only self.ursula_url = ursula_url self.ursula = Ursula.from_seed_and_stake_info( seed_uri=self.ursula_url, federated_only=self.federated_only, minimum_stake=0) self.arweave_wallet = None if arweave_wallet_file_path: self.arweave_wallet = arweave.Wallet(arweave_wallet_file_path) self.ipfs = None if ipfs_addr: self.ipfs = ipfshttpclient.connect(ipfs_addr) self.temp_dir = os.path.join('/', 'tmp', dir_name) self.alice_config = AliceConfiguration( provider_uri=provider_uri, checksum_address=checksum_address, signer_uri=signer_uri, config_root=os.path.join(self.temp_dir), domain=domain, known_nodes={self.ursula}, start_learning_now=False, federated_only=self.federated_only, learn_on_same_thread=True) try: if os.path.exists(os.path.join(self.temp_dir, "alice.json")): raise ExistingKeyringError() self.alice_config.initialize(password=passphrase) except ExistingKeyringError: self.alice_config = AliceConfiguration.from_configuration_file( filepath=os.path.join(self.temp_dir, "alice.json"), known_nodes={self.ursula}, start_learning_now=False) self.alice_config.attach_keyring() self.alice_config.keyring.unlock(password=passphrase) signer = Signer.from_signer_uri(signer_uri) if signer_uri else None if signer: signer.unlock_account(account=checksum_address, password=client_password) self.alice = self.alice_config.produce(signer=signer) try: self.alice_config_file = self.alice_config.to_configuration_file() except FileExistsError: pass self.alice.start_learning_loop(now=True) self.privkeys, self.pubkeys = fetch_keys(path=self.temp_dir) bob_enc_keypair = DecryptingKeypair(private_key=self.privkeys["enc"]) bob_sig_keypair = SigningKeypair(private_key=self.privkeys["sig"]) enc_power = DecryptingPower(keypair=bob_enc_keypair) sig_power = SigningPower(keypair=bob_sig_keypair) power_ups = [enc_power, sig_power] self.bob = Bob(domain=domain, federated_only=self.federated_only, crypto_power_ups=power_ups, start_learning_now=True, abort_on_learning_error=True, known_nodes=[self.ursula], save_metadata=False, network_middleware=RestMiddleware(), provider_uri=provider_uri)
# We expect the url of the seednode as the first argument. SEEDNODE_URL = 'localhost:11500' ####################################### # Alicia, the Authority of the Policy # ####################################### # We get a persistent Alice. # If we had an existing Alicia in disk, let's get it from there passphrase = "TEST_ALICIA_INSECURE_DEVELOPMENT_PASSWORD" try: alice_config_file = os.path.join(TEMP_ALICE_DIR, "alice.config") new_alice_config = AliceConfiguration.from_configuration_file( filepath=alice_config_file, network_middleware=RestMiddleware(), start_learning_now=False, save_metadata=False, ) alicia = new_alice_config(passphrase=passphrase) except: # If anything fails, let's create Alicia from scratch # Remove previous demo files and create new ones shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True) ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL, federated_only=True, minimum_stake=0)
def alicia_encrypt(data_fields, pid): POLICY_FILENAME = "policy-metadata.json" globalLogPublisher.addObserver(SimpleObserver()) TEMP_ALICE_DIR = "alicia-files".format( os.path.dirname(os.path.abspath(__file__))) SEEDNODE_URL = 'localhost:11500' passphrase = "TEST_ALICIA_INSECURE_DEVELOPMENT_PASSWORD" try: alice_config_file = os.path.join(TEMP_ALICE_DIR, "alice.config") new_alice_config = AliceConfiguration.from_configuration_file( filepath=alice_config_file, network_middleware=RestMiddleware(), start_learning_now=False, save_metadata=False, ) alicia = new_alice_config(passphrase=passphrase) except: shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True) ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL, federated_only=True, minimum_stake=0) alice_config = AliceConfiguration( config_root=os.path.join(TEMP_ALICE_DIR), is_me=True, known_nodes={ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) alice_config.initialize(password=passphrase) alice_config.keyring.unlock(password=passphrase) alicia = alice_config.produce() alice_config_file = alice_config.to_configuration_file() alicia.start_learning_loop(now=True) label = "doctor" label = label.encode() policy_pubkey = alicia.get_policy_pubkey_from_label(label) print("The policy public key for " "label '{}' is {}".format(label.decode("utf-8"), policy_pubkey.to_bytes().hex())) import data_ipfs res = data_ipfs.encrypt_patient_data(policy_pubkey, data_fields, pid, label=label, save_as_file=True) print(res) from doctor_keys import get_doctor_pubkeys doctor_pubkeys = get_doctor_pubkeys() powers_and_material = { DecryptingPower: doctor_pubkeys['enc'], SigningPower: doctor_pubkeys['sig'] } doctor_strange = Bob.from_public_keys( powers_and_material=powers_and_material, federated_only=True) policy_end_datetime = maya.now() + datetime.timedelta(days=5) m, n = 2, 3 print("Creating access policy for the Doctor...") policy = alicia.grant(bob=doctor_strange, label=label, m=m, n=n, expiration=policy_end_datetime) print("Done!") policy_info = { "policy_pubkey": policy.public_key.to_bytes().hex(), "alice_sig_pubkey": bytes(alicia.stamp).hex(), "label": label.decode("utf-8"), } filename = POLICY_FILENAME with open(filename, 'w') as f: json.dump(policy_info, f) return res
def test_alices_powers_are_persistent(federated_ursulas, tmpdir): passphrase = TEST_URSULA_INSECURE_DEVELOPMENT_PASSWORD # Let's create an Alice from a Configuration. # This requires creating a local storage for her first. node_storage = LocalFileBasedNodeStorage( federated_only=True, character_class=Ursula, # Alice needs to store some info about Ursula known_metadata_dir=os.path.join(tmpdir, "known_metadata"), ) alice_config = AliceConfiguration( config_root=os.path.join(tmpdir, "config_root"), node_storage=node_storage, auto_initialize=True, auto_generate_keys=True, passphrase=passphrase, is_me=True, network_middleware=MockRestMiddleware(), known_nodes=federated_ursulas, start_learning_now=False, federated_only=True, save_metadata=False, load_metadata=False ) alice = alice_config(passphrase=passphrase) # We will save Alice's config to a file for later use alice_config_file = alice_config.to_configuration_file() # Let's save Alice's public keys too to check they are correctly restored later alices_verifying_key = alice.public_keys(SigningPower) alices_receiving_key = alice.public_keys(EncryptingPower) # Next, let's fix a label for all the policies we will create later. label = b"this_is_the_path_to_which_access_is_being_granted" # Even before creating the policies, we can know what will be its public key. # This can be used by DataSources to encrypt messages before Alice grants access to Bobs policy_pubkey = alice.get_policy_pubkey_from_label(label) # Now, let's create a policy for some Bob. m, n = 3, 4 policy_end_datetime = maya.now() + datetime.timedelta(days=5) bob = Bob(federated_only=True, start_learning_now=False, network_middleware=MockRestMiddleware(), ) bob_policy = alice.grant(bob, label, m=m, n=n, expiration=policy_end_datetime) assert policy_pubkey == bob_policy.public_key # ... and Alice and her configuration disappear. del alice del alice_config ################################### # Some time passes. # # ... # # (jmyles plays the Song of Time) # # ... # # Alice appears again. # ################################### # A new Alice is restored from the configuration file new_alice_config = AliceConfiguration.from_configuration_file( filepath=alice_config_file, network_middleware=MockRestMiddleware(), known_nodes=federated_ursulas, start_learning_now=False, ) new_alice = new_alice_config(passphrase=passphrase) # First, we check that her public keys are correctly restored assert alices_verifying_key == new_alice.public_keys(SigningPower) assert alices_receiving_key == new_alice.public_keys(EncryptingPower) # Bob's eldest brother, Roberto, appears too roberto = Bob(federated_only=True, start_learning_now=False, network_middleware=MockRestMiddleware(), ) # Alice creates a new policy for Roberto. Note how all the parameters # except for the label (i.e., recipient, m, n, policy_end) are different # from previous policy m, n = 2, 5 policy_end_datetime = maya.now() + datetime.timedelta(days=3) roberto_policy = new_alice.grant(roberto, label, m=m, n=n, expiration=policy_end_datetime) # Both policies must share the same public key (i.e., the policy public key) assert policy_pubkey == roberto_policy.public_key
def subscribe_and_grant_permission_to(username): globalLogPublisher.addObserver(SimpleObserver()) # Reinitialize Alice from our config file ALICE_CONFIG_DIR = os.path.join(settings.BASE_DIR, 'nucypher_utils', 'nucypher_data', 'nucypher_char_configs', 'stridon-demo-alice') ALICE_CONFIG_FILE = os.path.join(ALICE_CONFIG_DIR, "alice.config") passphrase = "TEST_ALICE_PASSWORD" new_alice_config = AliceConfiguration.from_configuration_file( filepath=ALICE_CONFIG_FILE, network_middleware=RestMiddleware(), start_learning_now=False, save_metadata=False, ) new_alice_config.keyring.unlock(password=passphrase) alice = new_alice_config() # Now onto Bob SEEDNODE_URL = 'localhost:11500' BOB_CONFIG_DIR = os.path.join(settings.BASE_DIR, 'nucypher_utils', 'nucypher_data', 'nucypher_char_configs', username) ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL, federated_only=True, minimum_stake=0) bob_config = BobConfiguration( config_root=os.path.join(BOB_CONFIG_DIR), is_me=True, known_nodes={ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) bob_config.initialize(password=passphrase) bob_config.keyring.unlock(password=passphrase) bob_config_file = bob_config.to_configuration_file() premium_user = bob_config.produce() policy_end_datetime = maya.now() + datetime.timedelta(days=5) label = b'stridon-premium-service' policy_pubkey = alice.get_policy_pubkey_from_label(label) alice.start_learning_loop(now=True) policy = alice.grant(bob=premium_user, label=label, m=1, n=1, expiration=policy_end_datetime) assert policy.public_key == policy_pubkey alices_pubkey_bytes = bytes(alice.stamp) premium_user.join_policy(label, alices_pubkey_bytes) from nucypher.crypto.powers import SigningPower, DecryptingPower print("ALICE") print(alice.public_keys(SigningPower)) print(alice.public_keys(DecryptingPower)) print("PREMIUM_USER") print(premium_user.public_keys(SigningPower)) print(premium_user.public_keys(DecryptingPower)) return policy.public_key == policy_pubkey
def encryptData(): # { the object received in the request # "fileFieldCount": 2, # "textFieldCount": 2, # "0": "1st File", # "1": "2nd File", # "fileNames (stringified)": { # "0": "blood", # "1": "2nd File Name" # }, # "textFields (stringified)": { # "age": "18", # "name": "arvind" # } # # "username": "******", # "password": "******", # "hash": "", # "alice": "/home/arvind/Documents/ethDenver/umbral/alice/arvind/alice.config", # "label": "1stlabel" # # } json_data = request.form.to_dict() fileFieldCount= int(json_data['fileFieldCount']) # object that contains the files file_obj={} # object that contains all the other form fields form_field_obj ={} print("requetssss ------") print(request.files.to_dict()) print(request.form.to_dict()) print('json_data') print(json_data) fileNames = json.loads(json_data['fileNames']) textFields = json.loads(json_data['textFields']) for i in range(0, fileFieldCount): file_obj[fileNames[str(i)]] = request.files[str(i)].read() textFieldsKeys = list(textFields.keys()) for key in textFieldsKeys: form_field_obj[key] = textFields[key] data_obj = {} data_obj['file_obj'] = file_obj data_obj['form_field_obj'] = form_field_obj label = json_data['label'] aliceFile = json_data['alice'] password = json_data['password'] file_url = '/tmp/' + label + '.json' label = label.encode() hash = data_obj obj_to_be_stored = createDataObject(hash, json_data['label']) f = open(file_url, 'w') f.write(json.dumps(obj_to_be_stored)) f.close() alice_config = AliceConfiguration.from_configuration_file( filepath=aliceFile, known_nodes={ursula}, start_learning_now=False, ) alice_config.keyring.unlock(password=password) alicia = alice_config(domains={'TEMPORARY_DOMAIN'}) alicia.start_learning_loop(now=True) policy_pubkey = alicia.get_policy_pubkey_from_label(label) # Initialise Enrico enrico = Enrico(policy_encrypting_key=policy_pubkey) print ("Done upto 111") hash = msgpack.dumps(hash, use_bin_type=True) message_kit, _signature = enrico.encrypt_message(hash) message_kit_bytes = message_kit.to_bytes() newMsg = UmbralMessageKit.from_bytes(message_kit_bytes) print ("\n\ncheck") print (message_kit_bytes == newMsg.to_bytes()) print (message_kit) print (newMsg) data = {} data['message'] = message_kit_bytes.hex() data['label'] = label.decode('utf-8') data['policy_public_key'] = policy_pubkey.to_bytes().hex() data['alice_sig_pubkey'] = bytes(alicia.stamp).hex() data['data_source'] = bytes(enrico.stamp).hex() print ('result\n') print (data) print ('#####\n') return json.dumps(data)
def alice(click_config, action, quiet, teacher_uri, min_stake, http_port, discovery_port, federated_only, network, config_root, config_file, provider_uri, registry_filepath, dev, force, dry_run, bob_encrypting_key, bob_verifying_key, label, m, n): """ Start and manage an "Alice" character. """ if not quiet: click.secho(ALICE_BANNER) if action == 'init': """Create a brand-new persistent Alice""" if dev and not quiet: click.secho("WARNING: Using temporary storage area", fg='yellow') if not config_root: # Flag config_root = click_config.config_file # Envvar alice_config = AliceConfiguration.generate( password=click_config.get_password(confirm=True), config_root=config_root, rest_host="localhost", domains={network} if network else None, federated_only=federated_only, no_registry=True, # Yes we have no registry, registry_filepath=registry_filepath, provider_uri=provider_uri, ) if not quiet: click.secho("Generated keyring {}".format( alice_config.keyring_dir), fg='green') click.secho("Saved configuration file {}".format( alice_config.config_file_location), fg='green') # Give the use a suggestion as to what to do next... how_to_run_message = "\nTo run an Alice node from the default configuration filepath run: \n\n'{}'\n" suggested_command = 'nucypher alice run' if config_root is not None: config_file_location = os.path.join( config_root, config_file or AliceConfiguration.CONFIG_FILENAME) suggested_command += ' --config-file {}'.format( config_file_location) click.secho(how_to_run_message.format(suggested_command), fg='green') return # FIN else: click.secho("OK") elif action == "destroy": """Delete all configuration files from the disk""" if dev: message = "'nucypher ursula destroy' cannot be used in --dev mode" raise click.BadOptionUsage(option_name='--dev', message=message) destroy_system_configuration(config_class=AliceConfiguration, config_file=config_file, network=network, config_root=config_root, force=force) if not quiet: click.secho("Destroyed {}".format(config_root)) return # # Get Alice Configuration # if dev: alice_config = AliceConfiguration( dev_mode=True, domains={network}, provider_uri=provider_uri, federated_only=True, ) else: alice_config = AliceConfiguration.from_configuration_file( filepath=config_file, domains={network or GLOBAL_DOMAIN}, rest_port=discovery_port, provider_uri=provider_uri) # Teacher teacher_nodes = list() if teacher_uri: teacher_node = Ursula.from_teacher_uri( teacher_uri=teacher_uri, min_stake=min_stake, federated_only=alice_config.federated_only) teacher_nodes.append(teacher_node) if not dev: # Keyring try: click.secho("Decrypting keyring...", fg='blue') alice_config.keyring.unlock(password=click_config.get_password()) except CryptoError: raise alice_config.keyring.AuthenticationFailed finally: click_config.alice_config = alice_config # Produce ALICE = alice_config(known_nodes=teacher_nodes) if action == "run": # Alice Control alice_control = ALICE.make_wsgi_app() click.secho("Starting Alice Character Control...") click.secho(f"Alice Verifying Key {bytes(ALICE.stamp).hex()}", fg="green", bold=True) # Run if dry_run: return hx_deployer = HendrixDeploy(action="start", options={ "wsgi": alice_control, "http_port": http_port }) hx_deployer.run() # <--- Blocking Call to Reactor elif action == "view": """Paint an existing configuration to the console""" paint_configuration( config_filepath=config_file or alice_config.config_file_location) return elif action == "create-policy": if not all((bob_verifying_key, bob_encrypting_key, label)): raise click.BadArgumentUsage( message= "--bob-verifying-key, --bob-encrypting-key, and --label are " "required options to create a new policy.") request_data = { 'bob_encrypting_key': bob_encrypting_key, 'bob_signing_key': bob_verifying_key, 'label': b64encode(bytes(label, encoding='utf-8')).decode(), 'm': m, 'n': n, } response = requests.put(f'http://localhost:{http_port}/create_policy', data=json.dumps(request_data)) click.secho(response.json()) return elif action == "derive-policy": response = requests.post( f'http://localhost:{http_port}/derive_policy_pubkey/{label}') response_data = response.json() policy_encrypting_key = response_data['result'][ 'policy_encrypting_pubkey'] click.secho( f"Created new Policy with label {label} | {policy_encrypting_key}", fg='green') elif action == "grant": request_data = { 'bob_encrypting_key': bob_encrypting_key, 'bob_signing_key': bob_verifying_key, 'label': b64encode(bytes(label, encoding='utf-8')).decode(), 'm': m, 'n': n, 'expiration_time': (maya.now() + datetime.timedelta(days=3)).iso8601(), # TODO } response = requests.put(f'http://localhost:{http_port}/grant', data=json.dumps(request_data)) click.secho(response) return elif action == "revoke": raise NotImplementedError # TODO else: raise click.BadArgumentUsage(f"No such argument {action}")
def alice( click_config, action, # Mode dev, force, dry_run, # Network teacher_uri, min_stake, federated_only, network, discovery_port, controller_port, # Filesystem config_root, config_file, # Blockchain pay_with, provider_uri, geth, sync, poa, registry_filepath, hw_wallet, # Alice bob_encrypting_key, bob_verifying_key, label, m, n, value, rate, duration_periods, expiration, message_kit, ): """ "Alice the Policy Authority" management commands. \b Actions ------------------------------------------------- \b init Create a brand new persistent Alice view View existing Alice's configuration. run Start Alice's controller. destroy Delete existing Alice's configuration. public-keys Obtain Alice's public verification and encryption keys. derive-policy-pubkey Get a policy public key from a policy label. grant Create and enact an access policy for some Bob. revoke Revoke a policy. decrypt Decrypt data encrypted under an Alice's policy public key. """ # # Validate # if federated_only and geth: raise click.BadOptionUsage( option_name="--geth", message="Federated only cannot be used with the --geth flag") # Banner emitter = click_config.emitter emitter.clear() emitter.banner(ALICE_BANNER) # # Managed Ethereum Client # ETH_NODE = NO_BLOCKCHAIN_CONNECTION if geth: ETH_NODE = actions.get_provider_process() provider_uri = ETH_NODE.provider_uri(scheme='file') # # Eager Actions (No Authentication Required) # if action == 'init': """Create a brand-new persistent Alice""" if dev: raise click.BadArgumentUsage( "Cannot create a persistent development character") if not provider_uri and not federated_only: raise click.BadOptionUsage( option_name='--provider', message= "--provider is required to create a new decentralized alice.") if not config_root: # Flag config_root = click_config.config_file # Envvar if not pay_with and not federated_only: pay_with = select_client_account(emitter=emitter, provider_uri=provider_uri) new_alice_config = AliceConfiguration.generate( password=get_nucypher_password(confirm=True), config_root=config_root, checksum_address=pay_with, domains={network} if network else None, federated_only=federated_only, registry_filepath=registry_filepath, provider_process=ETH_NODE, poa=poa, provider_uri=provider_uri, m=m, n=n, duration_periods=duration_periods, rate=rate) painting.paint_new_installation_help( emitter, new_configuration=new_alice_config) return # Exit elif action == "view": """Paint an existing configuration to the console""" configuration_file_location = config_file or AliceConfiguration.default_filepath( ) response = AliceConfiguration._read_configuration_file( filepath=configuration_file_location) return emitter.ipc( response=response, request_id=0, duration=0) # FIXME: what are request_id and duration here? # # Get Alice Configuration # if dev: alice_config = AliceConfiguration( dev_mode=True, network_middleware=click_config.middleware, domains={network}, provider_process=ETH_NODE, provider_uri=provider_uri, federated_only=True) else: try: alice_config = AliceConfiguration.from_configuration_file( dev_mode=False, filepath=config_file, domains={network} if network else None, network_middleware=click_config.middleware, rest_port=discovery_port, checksum_address=pay_with, provider_process=ETH_NODE, provider_uri=provider_uri, registry_filepath=registry_filepath) except FileNotFoundError: return actions.handle_missing_configuration_file( character_config_class=AliceConfiguration, config_file=config_file) if action == "destroy": """Delete all configuration files from the disk""" if dev: message = "'nucypher alice destroy' cannot be used in --dev mode" raise click.BadOptionUsage(option_name='--dev', message=message) return actions.destroy_configuration(emitter, character_config=alice_config, force=force) # # Produce Alice # # TODO: OH MY. client_password = None if not alice_config.federated_only: if (not hw_wallet or not dev) and not click_config.json_ipc: client_password = get_client_password( checksum_address=alice_config.checksum_address) try: ALICE = actions.make_cli_character(character_config=alice_config, click_config=click_config, dev=dev, teacher_uri=teacher_uri, min_stake=min_stake, client_password=client_password) except NucypherKeyring.AuthenticationFailed as e: emitter.echo(str(e), color='red', bold=True) click.get_current_context().exit(1) # TODO: Exit codes (not only for this, but for other exceptions) # # Admin Actions # if action == "run": """Start Alice Controller""" try: # RPC if click_config.json_ipc: rpc_controller = ALICE.make_rpc_controller() _transport = rpc_controller.make_control_transport() rpc_controller.start() return # HTTP else: emitter.message( f"Alice Verifying Key {bytes(ALICE.stamp).hex()}", color="green", bold=True) controller = ALICE.make_web_controller( crash_on_error=click_config.debug) ALICE.log.info('Starting HTTP Character Web Controller') emitter.message( f'Running HTTP Alice Controller at http://localhost:{controller_port}' ) return controller.start(http_port=controller_port, dry_run=dry_run) # Handle Crash except Exception as e: alice_config.log.critical(str(e)) emitter.message(f"{e.__class__.__name__} {e}", color='red', bold=True) if click_config.debug: raise # Crash :-( return # # Alice API # elif action == "public-keys": response = ALICE.controller.public_keys() return response elif action == "derive-policy-pubkey": # Validate if not label: raise click.BadOptionUsage( option_name='label', message= "--label is required for deriving a policy encrypting key.") # Request return ALICE.controller.derive_policy_encrypting_key(label=label) elif action == "grant": # Validate if not all((bob_verifying_key, bob_encrypting_key, label)): raise click.BadArgumentUsage( message= "--bob-verifying-key, --bob-encrypting-key, and --label are " "required options to grant (optionally --m, --n, and --expiration)." ) # Request grant_request = { 'bob_encrypting_key': bob_encrypting_key, 'bob_verifying_key': bob_verifying_key, 'label': label, 'm': m, 'n': n, 'expiration': expiration, } if not ALICE.federated_only: grant_request.update({'value': value}) return ALICE.controller.grant(request=grant_request) elif action == "revoke": # Validate if not label and bob_verifying_key: raise click.BadArgumentUsage( message= f"--label and --bob-verifying-key are required options for revoke." ) # Request revoke_request = { 'label': label, 'bob_verifying_key': bob_verifying_key } return ALICE.controller.revoke(request=revoke_request) elif action == "decrypt": # Validate if not all((label, message_kit)): input_specification, output_specification = ALICE.controller.get_specifications( interface_name=action) required_fields = ', '.join(input_specification) raise click.BadArgumentUsage( f'{required_fields} are required flags to decrypt') # Request request_data = {'label': label, 'message_kit': message_kit} response = ALICE.controller.decrypt(request=request_data) return response else: raise click.BadArgumentUsage(f"No such argument {action}")
def alice(click_config, action, teacher_uri, min_stake, http_port, discovery_port, federated_only, network, config_root, config_file, provider_uri, no_registry, registry_filepath, dev, force, dry_run, bob_encrypting_key, bob_verifying_key, policy_encrypting_key, label, m, n): """ Start and manage an "Alice" character. """ if not click_config.json_ipc and not click_config.quiet: click.secho(ALICE_BANNER) if action == 'init': """Create a brand-new persistent Alice""" if not network: raise click.BadArgumentUsage( '--network is required to initialize a new configuration.') if dev: click_config.emitter( message="WARNING: Using temporary storage area", color='yellow') if not config_root: # Flag config_root = click_config.config_file # Envvar new_alice_config = AliceConfiguration.generate( password=click_config._get_password(confirm=True), config_root=config_root, rest_host="localhost", domains={network} if network else None, federated_only=federated_only, no_registry=no_registry, registry_filepath=registry_filepath, provider_uri=provider_uri) return painting.paint_new_installation_help( new_configuration=new_alice_config, config_root=config_root, config_file=config_file) elif action == "destroy": """Delete all configuration files from the disk""" if dev: message = "'nucypher ursula destroy' cannot be used in --dev mode" raise click.BadOptionUsage(option_name='--dev', message=message) destroyed_path = actions.destroy_system_configuration( config_class=AliceConfiguration, config_file=config_file, network=network, config_root=config_root, force=force) return nucypher_click_config.emitter( message=f"Destroyed {destroyed_path}", color='red') # # Get Alice Configuration # if dev: alice_config = AliceConfiguration( dev_mode=True, network_middleware=click_config.middleware, domains={network}, provider_uri=provider_uri, federated_only=True) else: alice_config = AliceConfiguration.from_configuration_file( filepath=config_file, domains={network or GLOBAL_DOMAIN}, network_middleware=click_config.middleware, rest_port=discovery_port, provider_uri=provider_uri) if not dev: click_config.unlock_keyring(character_configuration=alice_config) # Teacher Ursula teacher_uris = [teacher_uri] if teacher_uri else list() teacher_nodes = actions.load_seednodes( teacher_uris=teacher_uris, min_stake=min_stake, federated_only=federated_only, network_middleware=click_config.middleware) # Produce ALICE = alice_config(known_nodes=teacher_nodes, network_middleware=click_config.middleware) # Switch to character control emitter if click_config.json_ipc: ALICE.controller.emitter = IPCStdoutEmitter(quiet=click_config.quiet) if action == "run": """Start Alice Web Controller""" ALICE.controller.emitter( message=f"Alice Verifying Key {bytes(ALICE.stamp).hex()}", color="green", bold=True) controller = ALICE.make_web_controller( crash_on_error=click_config.debug) ALICE.log.info('Starting HTTP Character Web Controller') return controller.start(http_port=http_port, dry_run=dry_run) elif action == "view": """Paint an existing configuration to the console""" configuration_file_location = config_file or alice_config.config_file_location response = AliceConfiguration._read_configuration_file( filepath=configuration_file_location) return ALICE.controller.emitter( response=response) # TODO: Uses character control instead elif action == "public-keys": response = ALICE.controller.public_keys() return response elif action == "create-policy": if not all((bob_verifying_key, bob_encrypting_key, label)): raise click.BadArgumentUsage( message= "--bob-verifying-key, --bob-encrypting-key, and --label are " "required options to create a new policy.") create_policy_request = { 'bob_encrypting_key': bob_encrypting_key, 'bob_verifying_key': bob_verifying_key, 'label': label, 'm': m, 'n': n, } return ALICE.controller.create_policy(request=create_policy_request) elif action == "derive-policy-pubkey": return ALICE.controller.derive_policy_encrypting_key(label=label) elif action == "grant": grant_request = { 'bob_encrypting_key': bob_encrypting_key, 'bob_verifying_key': bob_verifying_key, 'label': label, 'm': m, 'n': n, 'expiration': (maya.now() + datetime.timedelta(days=3)).iso8601(), # TODO } return ALICE.controller.grant(request=grant_request) elif action == "revoke": return ALICE.controller.revoke( policy_encrypting_key=policy_encrypting_key) else: raise click.BadArgumentUsage(f"No such argument {action}")
def test_alices_powers_are_persistent(federated_ursulas, tmpdir): # Create a non-learning AliceConfiguration alice_config = AliceConfiguration(config_root=os.path.join( tmpdir, 'nucypher-custom-alice-config'), network_middleware=MockRestMiddleware(), known_nodes=federated_ursulas, start_learning_now=False, federated_only=True, save_metadata=False, reload_metadata=False) # Generate keys and write them the disk alice_config.initialize(password=INSECURE_DEVELOPMENT_PASSWORD) # Unlock Alice's keyring alice_config.keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) # Produce an Alice alice = alice_config() # or alice_config.produce() # Save Alice's node configuration file to disk for later use alice_config_file = alice_config.to_configuration_file() # Let's save Alice's public keys too to check they are correctly restored later alices_verifying_key = alice.public_keys(SigningPower) alices_receiving_key = alice.public_keys(DecryptingPower) # Next, let's fix a label for all the policies we will create later. label = b"this_is_the_path_to_which_access_is_being_granted" # Even before creating the policies, we can know what will be its public key. # This can be used by Enrico (i.e., a Data Source) to encrypt messages # before Alice grants access to Bobs. policy_pubkey = alice.get_policy_encrypting_key_from_label(label) # Now, let's create a policy for some Bob. m, n = 3, 4 policy_end_datetime = maya.now() + datetime.timedelta(days=5) bob = Bob(federated_only=True, start_learning_now=False, network_middleware=MockRestMiddleware()) bob_policy = alice.grant(bob, label, m=m, n=n, expiration=policy_end_datetime) assert policy_pubkey == bob_policy.public_key # ... and Alice and her configuration disappear. del alice del alice_config ################################### # Some time passes. # # ... # # (jmyles plays the Song of Time) # # ... # # Alice appears again. # ################################### # A new Alice is restored from the configuration file new_alice_config = AliceConfiguration.from_configuration_file( filepath=alice_config_file, network_middleware=MockRestMiddleware(), known_nodes=federated_ursulas, start_learning_now=False, ) # Alice unlocks her restored keyring from disk new_alice_config.attach_keyring() new_alice_config.keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) new_alice = new_alice_config() # First, we check that her public keys are correctly restored assert alices_verifying_key == new_alice.public_keys(SigningPower) assert alices_receiving_key == new_alice.public_keys(DecryptingPower) # Bob's eldest brother, Roberto, appears too roberto = Bob(federated_only=True, start_learning_now=False, network_middleware=MockRestMiddleware()) # Alice creates a new policy for Roberto. Note how all the parameters # except for the label (i.e., recipient, m, n, policy_end) are different # from previous policy m, n = 2, 5 policy_end_datetime = maya.now() + datetime.timedelta(days=3) roberto_policy = new_alice.grant(roberto, label, m=m, n=n, expiration=policy_end_datetime) # Both policies must share the same public key (i.e., the policy public key) assert policy_pubkey == roberto_policy.public_key
def decrypt_article(article_instance): username = article_instance.author.username DATASOURCE_FILENAME = f"\ {article_instance.author.username}-\ {article_instance.title}-\ datasource-pubkey.msgpack" DATA_SOURCE_DIR = os.path.join( settings.BASE_DIR, 'nucypher_utils', 'nucypher_data', ) with open( os.path.join( DATA_SOURCE_DIR, DATASOURCE_FILENAME ), "rb" ) as file: data = msgpack.load(file) data_source_public_key = data[b'data_source_public_key'] cipher_text = data[b'kits'] POLICY_FILENAME = "policy-metadata.json" POLICY_FILE = os.path.join( settings.BASE_DIR, 'nucypher_utils', 'nucypher_data', POLICY_FILENAME, ) with open(POLICY_FILE, 'r') as f: policy_pubkey_data = json.load(f) policy_pubkey_string = policy_pubkey_data['policy_pubkey'] policy_pubkey_bytes = unhexlify(policy_pubkey_string) policy_pubkey = keys.UmbralPublicKey.from_bytes(policy_pubkey_bytes) enrico_as_understood_by_bob = Enrico.from_public_keys( {SigningPower: data_source_public_key}, policy_encrypting_key=policy_pubkey, ) ALICE_CONFIG_DIR = os.path.join( settings.BASE_DIR, 'nucypher_utils', 'nucypher_data', 'nucypher_char_configs', 'stridon-demo-alice') ALICE_CONFIG_FILE = os.path.join( ALICE_CONFIG_DIR, "alice.config" ) passphrase = "TEST_ALICE_PASSWORD" new_alice_config = AliceConfiguration.from_configuration_file( filepath=ALICE_CONFIG_FILE, network_middleware=RestMiddleware(), start_learning_now=False, save_metadata=False, ) new_alice_config.keyring.unlock(password=passphrase) alice = new_alice_config() alice.start_learning_loop(now=True) alice_pubkey = keys.UmbralPublicKey.from_bytes(bytes(alice.stamp)) BOB_CONFIG_DIR = os.path.join( settings.BASE_DIR, 'nucypher_utils', 'nucypher_data', 'nucypher_char_configs', username) BOB_CONFIG_FILE = os.path.join( BOB_CONFIG_DIR, "bob.config" ) new_premium_user = BobConfiguration.from_configuration_file( filepath=BOB_CONFIG_FILE, network_middleware=RestMiddleware(), start_learning_now=False, save_metadata=False, ) new_premium_user.keyring.unlock(password=passphrase) premium_user = new_premium_user() policy_end_datetime = maya.now() + datetime.timedelta(days=5) label = b'stridon-premium-service' cipher_kit = kits.UmbralMessageKit.from_bytes(cipher_text) print("ALICE") print(alice.public_keys(SigningPower)) print(alice.public_keys(DecryptingPower)) print("PREMIUM_USER") print(premium_user.public_keys(SigningPower)) print(premium_user.public_keys(DecryptingPower)) try: delivered_cleartexts = premium_user.retrieve( message_kit=cipher_kit, data_source=enrico_as_understood_by_bob, alice_verifying_key=alice_pubkey, label=label ) failed = False plain_text_article_content = delivered_cleartexts[0] except KeyError: plain_text_article_content = '' failed = True return (plain_text_article_content, failed)