Esempio n. 1
0
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
Esempio n. 2
0
    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)
Esempio n. 3
0
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)
Esempio n. 4
0
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')
Esempio n. 5
0
    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
Esempio n. 6
0
    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
Esempio n. 7
0
    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)
Esempio n. 8
0
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
Esempio n. 9
0
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}")
Esempio n. 10
0
 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)
Esempio n. 11
0
# 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)
Esempio n. 12
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
Esempio n. 13
0
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
Esempio n. 14
0
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
Esempio n. 15
0
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)
Esempio n. 16
0
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}")
Esempio n. 17
0
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}")
Esempio n. 18
0
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
Esempio n. 20
0
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)