Example #1
0
def test_enrico_web_character_control_encrypt_message(
        enrico_web_controller_test_client, encrypt_control_request):
    method_name, params = encrypt_control_request
    endpoint = f'/{method_name}'
    response = enrico_web_controller_test_client.post(endpoint,
                                                      data=json.dumps(params))
    assert response.status_code == 200

    response_data = json.loads(response.data)
    assert 'message_kit' in response_data['result']
    assert 'signature' in response_data['result']

    # Check that it serializes correctly.
    UmbralMessageKit.from_bytes(
        b64decode(response_data['result']['message_kit']))

    # Send bad data to assert error return
    response = enrico_web_controller_test_client.post('/encrypt_message',
                                                      data=json.dumps(
                                                          {'bad': 'input'}))
    assert response.status_code == 400

    del (params['message'])
    response = enrico_web_controller_test_client.post('/encrypt_message',
                                                      data=params)
    assert response.status_code == 400
Example #2
0
    def decrypt(self, channel_reader: object) -> bytes:
        '''
        Decrypt extsting message using ChannelReader instance
        :param BOB:
        :return:
        '''
        policy_pubkey_restored = UmbralPublicKey.from_bytes(
            self.policy_pubkey_bytes)

        data_source_restored = Enrico.from_public_keys(
            {SigningPower: self.data_source_pubkey_bytes},
            policy_encrypting_key=policy_pubkey_restored)

        channel_reader.BOB.join_policy(self.label_bytes,
                                       self.alice_pubkey_bytes)

        alices_sig_pubkey = UmbralPublicKey.from_bytes(
            bytes(self.alice_pubkey_bytes))
        message_kit_object = UmbralMessageKit.from_bytes(self.kit_bytes)

        return channel_reader.BOB.retrieve(
            message_kit=message_kit_object,
            data_source=data_source_restored,
            alice_verifying_key=alices_sig_pubkey,
            label=self.label_bytes)
Example #3
0
    def decrypt(self, label: bytes, message_kit: bytes) -> dict:
        """
        Character control endpoint to allow Alice to decrypt her own data.
        """

        from nucypher.characters.lawful import Enrico
        policy_encrypting_key = self.character.get_policy_encrypting_key_from_label(label)

        # TODO #846: May raise UnknownOpenSSLError and InvalidTag.
        message_kit = UmbralMessageKit.from_bytes(message_kit)

        enrico = Enrico.from_public_keys(
            verifying_key=message_kit.sender_verifying_key,
            policy_encrypting_key=policy_encrypting_key,
            label=label
        )

        plaintexts = self.character.decrypt_message_kit(
            message_kit=message_kit,
            data_source=enrico,
            label=label
        )

        response = {'cleartexts': plaintexts}
        return response
Example #4
0
    def set_policy(id_as_hex):
        """
        REST endpoint for setting a kFrag.
        TODO: Instead of taking a Request, use the apistar typing system to type
            a payload and validate / split it.
        TODO: Validate that the kfrag being saved is pursuant to an approved
            Policy (see #121).
        """
        policy_message_kit = UmbralMessageKit.from_bytes(request.data)

        alices_verifying_key = policy_message_kit.sender_verifying_key
        alice = _alice_class.from_public_keys(verifying_key=alices_verifying_key)

        try:
            cleartext = this_node.verify_from(alice, policy_message_kit, decrypt=True)
        except InvalidSignature:
            # TODO: Perhaps we log this?
            return Response(status_code=400)

        kfrag = KFrag.from_bytes(cleartext)

        if not kfrag.verify(signing_pubkey=alices_verifying_key):
            raise InvalidSignature("{} is invalid".format(kfrag))

        with ThreadedSession(db_engine) as session:
            datastore.attach_kfrag_to_saved_arrangement(
                alice,
                id_as_hex,
                kfrag,
                session=session)

        # TODO: Sign the arrangement here.  #495
        return ""  # TODO: Return A 200, with whatever policy metadata.
Example #5
0
 def decrypt(self, bob, item_cid, pol, sig, lab):
     policy_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(pol))
     alices_sig_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(sig))
     label = lab.encode()
     dat = self.ipfs_gateway_api.cat(item_cid)
     doctor = bob
     doctor.join_policy(label, alices_sig_pubkey)
     data = msgpack.loads(dat, raw=False)
     message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits'])
     data_source = Enrico.from_public_keys(
         {SigningPower: data['data_source']},
         policy_encrypting_key=policy_pubkey
     )
     message_kit = next(message_kits)
     start = timer()
     retrieved_plaintexts = doctor.retrieve(
         label=label,
         message_kit=message_kit,
         data_source=data_source,
         alice_verifying_key=alices_sig_pubkey
     )
     end = timer()
     plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False)
     heart_rate = plaintext['heart_rate']
     timestamp = maya.MayaDT(plaintext['timestamp'])
     terminal_size = shutil.get_terminal_size().columns
     max_width = min(terminal_size, 120)
     columns = max_width - 12 - 27
     scale = columns / 40
     retrieval_time = "Retrieval time: {:8.2f} ms".format(1000 * (end - start))
     line = heart_rate# + "   " + retrieval_time
     return line
Example #6
0
    def retrieve(self,
                 label: bytes,
                 policy_encrypting_key: bytes,
                 alice_verifying_key: bytes,
                 message_kit: bytes):
        """
        Character control endpoint for re-encrypting and decrypting policy data.
        """
        from nucypher.characters.lawful import Enrico

        policy_encrypting_key = UmbralPublicKey.from_bytes(policy_encrypting_key)
        alice_pubkey_sig = UmbralPublicKey.from_bytes(alice_verifying_key)
        message_kit = UmbralMessageKit.from_bytes(message_kit)  # TODO: May raise UnknownOpenSSLError and InvalidTag.

        data_source = Enrico.from_public_keys({SigningPower: message_kit.sender_pubkey_sig},
                                              policy_encrypting_key=policy_encrypting_key,
                                              label=label)

        self.bob.join_policy(label=label, alice_pubkey_sig=alice_pubkey_sig)
        plaintexts = self.bob.retrieve(message_kit=message_kit,
                                       data_source=data_source,
                                       alice_verifying_key=alice_pubkey_sig,
                                       label=label)

        response_data = {'cleartexts': plaintexts}
        return response_data
Example #7
0
    def set_policy(self, id_as_hex, request: http.Request):
        """
        REST endpoint for setting a kFrag.
        TODO: Instead of taking a Request, use the apistar typing system to type
            a payload and validate / split it.
        TODO: Validate that the kfrag being saved is pursuant to an approved
            Policy (see #121).
        """
        policy_message_kit = UmbralMessageKit.from_bytes(request.body)

        alice = self._alice_class.from_public_keys(
            {SigningPower: policy_message_kit.sender_pubkey_sig})

        try:
            cleartext = self.verify_from(alice,
                                         policy_message_kit,
                                         decrypt=True)
        except self.InvalidSignature:
            # TODO: What do we do if the Policy isn't signed properly?
            pass

        kfrag = KFrag.from_bytes(cleartext)

        with ThreadedSession(self.db_engine) as session:
            self.datastore.attach_kfrag_to_saved_arrangement(alice,
                                                             id_as_hex,
                                                             kfrag,
                                                             session=session)

        return  # TODO: Return A 200, with whatever policy metadata.
Example #8
0
def test_enrico_character_control_encrypt_message(enrico_control_test_client):
    request_data = {
        'message':
        b64encode(
            b"The admiration I had for your work has completely evaporated!").
        decode(),
    }

    response = enrico_control_test_client.post('/encrypt_message',
                                               data=json.dumps(request_data))
    assert response.status_code == 200

    response_data = json.loads(response.data)
    assert 'message_kit' in response_data['result']
    assert 'signature' in response_data['result']

    # Check that it serializes correctly.
    message_kit = UmbralMessageKit.from_bytes(
        b64decode(response_data['result']['message_kit']))

    # Send bad data to assert error return
    response = enrico_control_test_client.post('/encrypt_message',
                                               data=json.dumps(
                                                   {'bad': 'input'}))
    assert response.status_code == 400

    del (request_data['message'])
    response = enrico_control_test_client.post('/encrypt_message',
                                               data=request_data)
    assert response.status_code == 400
def decrypting_msg(data, policy_pubkey, label, arjuns_sig_pubkey, mayank):
    data = msgpack.loads(data, raw=False)
    print("afterjson", data)
    message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits'])

    # The mayank also needs to create a view of the Data Source from its public keys
    data_source = DataSource.from_public_keys(
            policy_public_key=policy_pubkey,
            datasource_public_key=data['data_source'],
            label=label
    )

    # NuCypher network to get a re-encrypted version of each MessageKit.
    for message_kit in message_kits:
        try:
            start = timer()
            retrieved_plaintexts = mayank.retrieve(
                message_kit=message_kit,
                data_source=data_source,
                alice_verifying_key=arjuns_sig_pubkey
            )
            end = timer()

            plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False)

            msg = plaintext['msg']
            name = plaintext['name']
            timestamp = maya.MayaDT(plaintext['timestamp'])

            return (name+": "+msg+" ("+str(timestamp)+")")
            
        except Exception as e:
            traceback.print_exc()
Example #10
0
    def retrieve(self,
                 label: bytes,
                 policy_encrypting_key: bytes,
                 alice_verifying_key: bytes,
                 message_kit: bytes,
                 treasure_map: Union[bytes, str, 'TreasureMap'] = None):
        """
        Character control endpoint for re-encrypting and decrypting policy data.
        """
        from nucypher.characters.lawful import Enrico

        policy_encrypting_key = UmbralPublicKey.from_bytes(
            policy_encrypting_key)
        alice_verifying_key = UmbralPublicKey.from_bytes(alice_verifying_key)
        message_kit = UmbralMessageKit.from_bytes(
            message_kit
        )  # TODO #846: May raise UnknownOpenSSLError and InvalidTag.

        enrico = Enrico.from_public_keys(
            verifying_key=message_kit.sender_verifying_key,
            policy_encrypting_key=policy_encrypting_key,
            label=label)

        self.character.join_policy(label=label,
                                   alice_verifying_key=alice_verifying_key)

        plaintexts = self.character.retrieve(
            message_kit,
            enrico=enrico,
            alice_verifying_key=alice_verifying_key,
            label=label,
            treasure_map=treasure_map)

        response_data = {'cleartexts': plaintexts}
        return response_data
Example #11
0
def reencrypt_segment(enc_data, policy_metadata, listener):
    policy_pubkey = UmbralPublicKey.from_bytes(
        bytes.fromhex(policy_metadata["policy_pubkey"]))
    alices_sig_pubkey = UmbralPublicKey.from_bytes(
        bytes.fromhex(policy_metadata["alice_sig_pubkey"]))
    label = policy_metadata["label"].encode()

    data = msgpack.loads(enc_data)
    message_kit = UmbralMessageKit.from_bytes((data[b'track_segment_data']))
    data_source = Enrico.from_public_keys(verifying_key=data[b'data_source'],
                                          policy_encrypting_key=policy_pubkey)
    plaintext = None
    try:
        start = timer()
        retrieved_plaintexts = listener.retrieve(
            message_kit,
            label=label,
            enrico=data_source,
            alice_verifying_key=alices_sig_pubkey)
        end = timer()
        plaintext = retrieved_plaintexts[0]

    except Exception as e:
        # We just want to know what went wrong and continue the demo
        traceback.print_exc()
    return plaintext
Example #12
0
    def decrypt_data(self, data_source_public_key, data, policy_info):
        """
        Decrypt data

        Args:
            data_source_public_key (bytes): data_source_public_key
            data (bytes): encrypted data
            policy_info (dict): dict containing policy_pubkey, alice_sig_pubkey and label keys

        Returns:
            retrieved_plaintexts (list): list of str
        """
        policy_pubkey = UmbralPublicKey.from_bytes(
            bytes.fromhex(policy_info["policy_pubkey"]))
        alice_sig_pubkey = UmbralPublicKey.from_bytes(
            bytes.fromhex(policy_info["alice_sig_pubkey"]))
        label = policy_info["label"].encode()
        self.bob.join_policy(label, alice_sig_pubkey)
        message_kit = UmbralMessageKit.from_bytes(data)
        data_source = Enrico.from_public_keys(
            verifying_key=data_source_public_key,
            policy_encrypting_key=policy_pubkey)
        retrieved_plaintexts = self.bob.retrieve(
            message_kit,
            label=label,
            enrico=data_source,
            alice_verifying_key=alice_sig_pubkey)
        retrieved_plaintexts = [
            x.decode('utf-8') for x in retrieved_plaintexts
        ]
        return retrieved_plaintexts
Example #13
0
    def set_policy(id_as_hex):
        """
        REST endpoint for setting a kFrag.
        """
        policy_message_kit = UmbralMessageKit.from_bytes(request.data)

        alices_verifying_key = policy_message_kit.sender_verifying_key
        alice = _alice_class.from_public_keys(
            verifying_key=alices_verifying_key)

        try:
            cleartext = this_node.verify_from(alice,
                                              policy_message_kit,
                                              decrypt=True)
        except InvalidSignature:
            # TODO: Perhaps we log this?  Essentially 355.
            return Response(status_code=400)

        if not this_node.federated_only:
            # This splitter probably belongs somewhere canonical.
            transaction_splitter = BytestringSplitter(32)
            tx, kfrag_bytes = transaction_splitter(cleartext,
                                                   return_remainder=True)

            try:
                # Get all of the arrangements and verify that we'll be paid.
                # TODO: We'd love for this part to be impossible to reduce the risk of collusion.  #1274
                arranged_addresses = this_node.policy_agent.fetch_arrangement_addresses_from_policy_txid(
                    tx, timeout=this_node.synchronous_query_timeout)
            except TimeExhausted:
                # Alice didn't pay.  Return response with that weird status code.
                this_node.suspicious_activities_witnessed['freeriders'].append(
                    (alice, f"No transaction matching {tx}."))
                return Response(status=402)

            this_node_has_been_arranged = this_node.checksum_address in arranged_addresses
            if not this_node_has_been_arranged:
                this_node.suspicious_activities_witnessed['freeriders'].append(
                    (alice,
                     f"The transaction {tx} does not list me as a Worker - it lists {arranged_addresses}."
                     ))
                return Response(status=402)
        else:
            _tx = NO_BLOCKCHAIN_CONNECTION
            kfrag_bytes = cleartext
        kfrag = KFrag.from_bytes(kfrag_bytes)

        if not kfrag.verify(signing_pubkey=alices_verifying_key):
            raise InvalidSignature("{} is invalid".format(kfrag))

        with datastore.describe(PolicyArrangement, id_as_hex,
                                writeable=True) as policy_arrangement:
            if not policy_arrangement.alice_verifying_key == alice.stamp.as_umbral_pubkey(
            ):
                raise alice.SuspiciousActivity
            policy_arrangement.kfrag = kfrag

        # TODO: Sign the arrangement here.  #495
        return ""  # TODO: Return A 200, with whatever policy metadata.
Example #14
0
def decrypt_for_policy():
    """
    input:
        {
            "label": "",
            "message_kit": "",
            "alice_pubkey": "",
            "bob_privkey": "",
            "policy_pubkey": "",
            "data_source_pubkey": ""
        }

    response:
        {
            "success": "",
            "cleartext": "",
            "err_msg": ""
        }
    """
    result = {'success': False, 'cleartext': None, 'err_msg': None}

    try:
        j = json.loads(request.data.decode('utf-8'))

        # TODO: Check if the input is valid

        # Parse the input values
        label = j['label'].encode('utf-8')
        message_kit = UmbralMessageKit.from_bytes(
            base64.urlsafe_b64decode(j['message_kit']))
        alice_pubkey = UmbralPublicKey.from_bytes(
            j['alice_pubkey'], decoder=base64.urlsafe_b64decode)
        bob_privkey = UmbralPrivateKey.from_bytes(
            j['bob_privkey'], decoder=base64.urlsafe_b64decode)
        policy_pubkey = UmbralPublicKey.from_bytes(
            j['policy_pubkey'], decoder=base64.urlsafe_b64decode)
        data_source_pubkey = UmbralPublicKey.from_bytes(
            j['data_source_pubkey'], decoder=base64.urlsafe_b64decode)

        # Encrypt plaintext for policy
        cleartext = api.decrypt_for_policy(label, message_kit, alice_pubkey,
                                           bob_privkey, policy_pubkey,
                                           data_source_pubkey)

        # Format the response data
        result['cleartext'] = base64.urlsafe_b64encode(cleartext).decode(
            'utf8')

        result['success'] = True
    except Exception as e:
        result['success'] = False
        result['err_msg'] = str(e)

    # Create response
    response = jsonify(result)
    return response
Example #15
0
    def get(self):
        "User should send Bob password to decrypt files"

        try:
            user = request.args.get("user")
            pw = request.args.get("password")
            label = request.args.get("label")
            frmt = request.args.get("frmt")

        except:
            response = {'message': "Insufficient Query Params"}

            return make_response(jsonify(response)), 404

        keyringBob = NucypherKeyring(account=user)

        keyringBob.unlock(password=pw)

        bob = Bob(keyring=keyringBob,
                  known_nodes=[ursula],
                  federated_only=True,
                  learn_on_same_thread=True,
                  domain=TEMPORARY_DOMAIN)

        bob.join_policy(label.encode(), alice_sig_pubkey)

        from nucypher.characters.lawful import Enrico

        global globalStorage

        enrico1 = Enrico.from_public_keys(
            verifying_key=globalStorage[label]["data_source_public_key"],
            policy_encrypting_key=globalStorage[label]["policy_pubkey"])

        imgUrl = base_uri + label + "." + frmt
        response = requests.get(imgUrl)

        ciphertext = UmbralMessageKit.from_bytes(response.content)

        decrypted_plaintext = bob.retrieve(
            ciphertext,
            label=label.encode(),
            enrico=enrico1,
            alice_verifying_key=alice_sig_pubkey)

        return send_file(io.BytesIO(decrypted_plaintext[0]),
                         mimetype="image/" + frmt,
                         as_attachment=False,
                         attachment_filename='{}.'.format(label) + frmt), 200
    def downloadFile(self, username, receipt, policy_info):
        hash = receipt['hash_key']
        input = self.ipfs_gateway_api.cat(hash)

        enc_privkey, sig_privkey = self.reveal_private_keys(username)

        bob_enc_key = DecryptingKeypair(private_key=enc_privkey)
        bob_sig_keyp = SigningKeypair(private_key=sig_privkey)
        enc_power = DecryptingPower(keypair=bob_enc_key)
        sig_power = SigningPower(keypair=bob_sig_keyp)
        power_ups = [enc_power, sig_power]

        self.Bob = Bob(
            federated_only=True,
            crypto_power_ups=power_ups,
            start_learning_now=True,
            abort_on_learning_error=True,
            known_nodes=[self.ursula], 
            save_metadata=False,
            network_middleware=RestMiddleware(),
        )

        policy_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(policy_info["policy_pubkey"]))

        enrico = Enrico.from_public_keys(
            {SigningPower: UmbralPublicKey.from_bytes(bytes.fromhex(receipt['data_source_public_key']))},
            policy_encrypting_key=policy_pubkey
        )
        alice_pubkey_restored = UmbralPublicKey.from_bytes(base58.b58decode(policy_info['alice_sig_pubkey']))
        self.Bob.join_policy(policy_info['label'].encode(), alice_pubkey_restored)

        data = msgpack.loads(input, raw=False)
        message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits'])
        message_kit = next(message_kits)

        retrieved_plaintexts = self.Bob.retrieve(
            message_kit,
            enrico=enrico,
            alice_verifying_key=alice_pubkey_restored,
            label=policy_info['label'].encode(),
        )

        plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False)
        print(plaintext)
        decrypted_data = plaintext['data']
        return decrypted_data
Example #17
0
def reencrypt_data(data_filepath, policy_filename, listener):
    '''
    Now that the listener joined the policy in the NuCypher network,
    he can retrieve encrypted data which he can decrypt with his private key.
    '''

    with open(policy_filename, 'r') as f:
        policy_data = json.load(f)

    policy_pubkey = UmbralPublicKey.from_bytes(
        bytes.fromhex(policy_data["policy_pubkey"]))
    alices_sig_pubkey = UmbralPublicKey.from_bytes(
        bytes.fromhex(policy_data["alice_sig_pubkey"]))
    label = policy_data["label"].encode()

    track_encrypted_files = os.scandir(data_filepath)
    for track_segment_encrypted in track_encrypted_files:
        if not track_segment_encrypted.name.endswith('_encrypted'):
            continue
        with open(track_segment_encrypted, 'rb') as f:
            data = msgpack.load(f)

        message_kit = UmbralMessageKit.from_bytes(data[b'track_segment_data'])
        data_source = Enrico.from_public_keys(
            verifying_key=data[b'data_source'],
            policy_encrypting_key=policy_pubkey)

        try:
            start = timer()
            retrieved_plaintexts = listener.retrieve(
                message_kit,
                label=label,
                enrico=data_source,
                alice_verifying_key=alices_sig_pubkey)
            end = timer()

            plaintext = retrieved_plaintexts[0]
            file_name = track_segment_encrypted.path[:-10] + "_decrypted.mp3"

            with open(file_name, 'wb') as f:
                f.write(plaintext)

        except Exception as e:
            # We just want to know what went wrong and continue the demo
            traceback.print_exc()
Example #18
0
    def post(self):
        keys = request.json['keys']
        path = self.writeKeys(keys)

        password = request.json['password']
        address = request.json['address']
        passwd = PBKDF2(password,
                        address.encode(),
                        20,
                        count=30000,
                        hmac_hash_module=SHA256).hex()
        keyring = NucypherKeyring(account=address, keyring_root="./keys")
        keyring.unlock(password=passwd)

        bob = Bob(known_nodes=[self.URSULA],
                  checksum_address=address,
                  domain='lynx',
                  keyring=keyring)

        enrico_key = request.json['enrico_key']
        policy_key = request.json['policy_key']
        data_source = Enrico.from_public_keys(
            verifying_key=bytes.fromhex(enrico_key),
            policy_encrypting_key=UmbralPublicKey.from_bytes(
                bytes.fromhex(policy_key)))

        ciphertext = request.json['ciphertext']
        message_kit = UmbralMessageKit.from_bytes(bytes.fromhex(ciphertext))

        label = request.json['label']
        alice_pubkey = request.json['alice_pubkey']
        alice_pubkey_umbral = UmbralPublicKey.from_bytes(
            bytes.fromhex(alice_pubkey))

        print("Retrieving...")
        retrieved_plaintexts = bob.retrieve(
            message_kit,
            label=label.encode(),
            enrico=data_source,
            alice_verifying_key=alice_pubkey_umbral)
        print("Retrieved.")
        result = retrieved_plaintexts[0].decode("utf-8")
        self.readAndDeleteKeys(address, keyring)  #delete keys
        return result
Example #19
0
    def get_treasure_map_from_known_ursulas(self, networky_stuff, map_id):
        """
        Iterate through swarm, asking for the TreasureMap.
        Return the first one who has it.
        TODO: What if a node gives a bunk TreasureMap?
        """
        from nucypher.network.protocols import dht_value_splitter
        for node in self.known_nodes.values():
            response = networky_stuff.get_treasure_map_from_node(node, map_id)

            if response.status_code == 200 and response.content:
                # TODO: Make this prettier
                header, _signature_for_ursula, pubkey_sig_alice, hrac, encrypted_treasure_map = \
                    dht_with_hrac_splitter(response.content, return_remainder=True)
                tmap_messaage_kit = UmbralMessageKit.from_bytes(
                    encrypted_treasure_map)
                return tmap_messaage_kit
            else:
                assert False
Example #20
0
def test_treasure_map_stored_by_ursula_is_the_correct_one_for_bob(alice, bob, ursulas, enacted_policy):
    """
    The TreasureMap given by Alice to Ursula is the correct one for Bob; he can decrypt and read it.
    """
    treasure_map_as_set_on_network = ursulas[0].server.storage[
        digest(enacted_policy.treasure_map_dht_key())]

    header, _signature_for_ursula, pubkey_sig_alice, hrac, encrypted_treasure_map = dht_with_hrac_splitter(
        treasure_map_as_set_on_network, return_remainder=True)

    assert header == constants.BYTESTRING_IS_TREASURE_MAP

    tmap_message_kit = UmbralMessageKit.from_bytes(encrypted_treasure_map)
    verified, treasure_map_as_decrypted_by_bob = bob.verify_from(alice,
                                           tmap_message_kit,
                                           decrypt=True,
                                           )

    assert treasure_map_as_decrypted_by_bob == enacted_policy.treasure_map.packed_payload()
    assert verified is True
Example #21
0
    def retrieve():
        """
        Character control endpoint for re-encrypting and decrypting policy
        data.
        """
        try:
            request_data = json.loads(request.data)

            label = b64decode(request_data['label'])
            policy_pubkey_enc = bytes.fromhex(
                request_data['policy_encrypting_pubkey'])
            alice_pubkey_sig = bytes.fromhex(
                request_data['alice_signing_pubkey'])
            datasource_pubkey_sig = bytes.fromhex(
                request_data['datasource_signing_pubkey'])
            message_kit = b64decode(request_data['message_kit'])
        except (KeyError, JSONDecodeError) as e:
            return Response(e, status=400)

        policy_pubkey_enc = UmbralPublicKey.from_bytes(policy_pubkey_enc)
        alice_pubkey_sig = UmbralPublicKey.from_bytes(alice_pubkey_sig)
        message_kit = UmbralMessageKit.from_bytes(message_kit)

        data_source = DataSource.from_public_keys(policy_pubkey_enc,
                                                  datasource_pubkey_sig,
                                                  label=label)
        drone_bob.join_policy(label=label, alice_pubkey_sig=alice_pubkey_sig)
        plaintexts = drone_bob.retrieve(message_kit=message_kit,
                                        data_source=data_source,
                                        alice_verifying_key=alice_pubkey_sig)

        plaintexts = [
            b64encode(plaintext).decode() for plaintext in plaintexts
        ]
        response_data = {
            'result': {
                'plaintext': plaintexts,
            }
        }

        return Response(json.dumps(response_data), status=200)
def test_message_kit_serialization_via_enrico(enacted_federated_policy,
                                              federated_alice):

    # Enrico
    enrico = Enrico.from_alice(federated_alice,
                               label=enacted_federated_policy.label)

    # Plaintext
    message = 'this is a message'
    plaintext_bytes = bytes(message, encoding='utf-8')

    # Create
    message_kit, signature = enrico.encrypt_message(plaintext=plaintext_bytes)

    # Serialize
    message_kit_bytes = message_kit.to_bytes()

    # Deserialize
    the_same_message_kit = UmbralMessageKit.from_bytes(message_kit_bytes)

    # Confirm
    assert message_kit_bytes == the_same_message_kit.to_bytes()
Example #23
0
    def set_policy(self, hrac_as_hex, request: http.Request):
        """
        REST endpoint for setting a kFrag.
        TODO: Instead of taking a Request, use the apistar typing system to type
            a payload and validate / split it.
        TODO: Validate that the kfrag being saved is pursuant to an approved
            Policy (see #121).
        """
        hrac = binascii.unhexlify(hrac_as_hex)
        policy_message_kit = UmbralMessageKit.from_bytes(request.body)
        # group_payload_splitter = BytestringSplitter(PublicKey)
        # policy_payload_splitter = BytestringSplitter((KFrag, KFRAG_LENGTH))

        alice = self._alice_class.from_public_keys(
            {SigningPower: policy_message_kit.sender_pubkey_sig})

        verified, cleartext = self.verify_from(alice,
                                               policy_message_kit,
                                               decrypt=True)

        if not verified:
            # TODO: What do we do if the Policy isn't signed properly?
            pass
        #
        # alices_signature, policy_payload =\
        #     BytestringSplitter(Signature)(cleartext, return_remainder=True)

        # TODO: If we're not adding anything else in the payload, stop using the
        # splitter here.
        # kfrag = policy_payload_splitter(policy_payload)[0]
        kfrag = KFrag.from_bytes(cleartext)

        with ThreadedSession(self.db_engine) as session:
            self.datastore.attach_kfrag_to_saved_arrangement(alice,
                                                             hrac_as_hex,
                                                             kfrag,
                                                             session=session)

        return  # TODO: Return A 200, with whatever policy metadata.
Example #24
0
    def decrypt(self, label: bytes, message_kit: bytes):
        """
        Character control endpoint to allow Alice to decrypt her own data.
        """

        from nucypher.characters.lawful import Enrico

        policy_encrypting_key = self.character.get_policy_pubkey_from_label(
            label)
        message_kit = UmbralMessageKit.from_bytes(
            message_kit
        )  # TODO #846: May raise UnknownOpenSSLError and InvalidTag.

        data_source = Enrico.from_public_keys(
            {SigningPower: message_kit.sender_pubkey_sig},
            policy_encrypting_key=policy_encrypting_key,
            label=label)

        plaintexts = self.alice.decrypt_message_kit(message_kit=message_kit,
                                                    data_source=data_source,
                                                    label=label)

        return {'cleartexts': plaintexts}
Example #25
0
policy_pubkey = PublicKey.from_bytes(
    bytes.fromhex(policy_data["policy_pubkey"]))
alices_sig_pubkey = PublicKey.from_bytes(
    bytes.fromhex(policy_data["alice_sig_pubkey"]))
label = policy_data["label"].encode()

print("The Doctor joins policy for label '{}'".format(label.decode("utf-8")))
doctor.join_policy(label, alices_sig_pubkey)

# Now that the Doctor joined the policy in the NuCypher network,
# he can retrieve encrypted data which he can decrypt with his private key.
# But first we need some encrypted data!
# Let's read the file produced by the heart monitor and unpack the MessageKits,
# which are the individual ciphertexts.
data = msgpack.load(open("heart_data.msgpack", "rb"), raw=False)
message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits'])

# The doctor also needs to create a view of the Data Source from its public keys
data_source = Enrico.from_public_keys(verifying_key=data['data_source'],
                                      policy_encrypting_key=policy_pubkey)

# Now he can ask the NuCypher network to get a re-encrypted version of each MessageKit.
for message_kit in message_kits:
    start = timer()
    retrieved_plaintexts = doctor.retrieve(
        message_kit,
        label=label,
        enrico=data_source,
        alice_verifying_key=alices_sig_pubkey)
    end = timer()
Example #26
0
def update_cached_decrypted_heartbeats_list(read_time, json_latest_values,
                                            bob_id):
    if int(read_time) == 0:
        # button never clicked but triggered by interval
        return None

    # Let's join the policy generated by Alicia. We just need some info about it.
    with open(POLICY_INFO_FILE, 'r') as f:
        policy_data = json.load(f)

    policy_pubkey = UmbralPublicKey.from_bytes(
        bytes.fromhex(policy_data['policy_pubkey']))
    alices_sig_pubkey = UmbralPublicKey.from_bytes(
        bytes.fromhex(policy_data['alice_sig_pubkey']))
    label = policy_data['label'].encode()

    if not joined:
        print("The Doctor joins policy for label '{}' "
              "and pubkey {}".format(policy_data['label'],
                                     policy_data['policy_pubkey']))

        bob.join_policy(label, alices_sig_pubkey)
        joined.append(label)

    with open(DATA_SOURCE_INFO_FILE, "rb") as file:
        data_source_metadata = msgpack.load(file, raw=False)

    cached_hb_values = collections.OrderedDict()
    if (json_latest_values
            is not None) and (json_latest_values != ACCESS_REVOKED):
        cached_hb_values = json.loads(
            json_latest_values, object_pairs_hook=collections.OrderedDict)

    last_timestamp = time.time() - 5  # last 5s
    if len(cached_hb_values) > 0:
        # use last timestamp
        last_timestamp = list(cached_hb_values.keys())[-1]

    # Bob also needs to create a view of the Data Source from its public keys
    data_source = DataSource.from_public_keys(
        policy_public_key=policy_pubkey,
        datasource_public_key=data_source_metadata['data_source_pub_key'],
        label=label)

    db_conn = sqlite3.connect(DB_FILE)
    try:
        df = pd.read_sql_query(
            'SELECT Timestamp, EncryptedData '
            'FROM {} '
            'WHERE Timestamp > "{}" '
            'ORDER BY Timestamp;'.format(DB_NAME, last_timestamp), db_conn)

        for index, row in df.iterrows():
            kit_bytes = bytes.fromhex(row['EncryptedData'])
            message_kit = UmbralMessageKit.from_bytes(kit_bytes)

            # Now he can ask the NuCypher network to get a re-encrypted version of each MessageKit.
            try:
                retrieved_plaintexts = bob.retrieve(
                    message_kit=message_kit,
                    data_source=data_source,
                    alice_verifying_key=alices_sig_pubkey)

                hb = msgpack.loads(retrieved_plaintexts[0], raw=False)
            except Exception as e:
                print(str(e))
                continue

            timestamp = row['Timestamp']
            cached_hb_values[timestamp] = hb
    finally:
        db_conn.close()

    # only cache last 30s
    while len(cached_hb_values) > 30:
        cached_hb_values.popitem(False)

    return json.dumps(cached_hb_values)
Example #27
0
def decryptDelegated():
    # Fetch Request Data
    # {
    #     "bobKeys": "{\"enc\": \"40f05590a27491caf37049366fefd43e46034e4308f4f1fd233c166bc3980ab4\", \"sig\": \"3bcf21d3cb160118b499a883023569c60476f8731bd9eade11016c5030c1ca5d\"}",
    #     "policy_public_key": "02aef01b40c0a62a9a1f650dd9a8381695e21a7b3826c748a5b64831aa0dd9862c",
    #     "alice_sig_pubkey": "036c5d361000e6fbf3c4a84c98f924a3206e8a72c758a67e8300b5bee111b5fa97",
    #     "label": "1stlabel",
    #     "message": "messagekit",
    #     "data_source": "03a38eef9fd09c9841585dea93791e139a3003d540539673c8c719af55e46c0c1b",
    # }
    json_data = json.loads(request.data.decode('utf-8'))
    bob_private_keys = json.loads(json_data['bobKeys'])
    policy_public_key = json_data['policy_public_key']
    alice_signing_key = json_data['alice_sig_pubkey']
    label = json_data['label']

    # username = json_data['username']

    message = json_data['message']
    data_source = json_data['data_source']

    data_source = bytes.fromhex(data_source)
    print (bob_private_keys['enc'])

    enc = UmbralPrivateKey.from_bytes(bytes.fromhex(bob_private_keys["enc"]))
    sig = UmbralPrivateKey.from_bytes(bytes.fromhex(bob_private_keys["sig"]))

    # signingPublic = sig.get_pubkey()
    # bobFilePath = os.path.join(os.getcwd(), 'bob/' + username + '.json')
    # doctor_pubkeys = _get_keys(bobFilePath, UmbralPublicKey)
    # print (signingPublic == doctor_pubkeys['sig'])
    # print (signingPublic)
    # print (doctor_pubkeys['sig'])
    print ('\n\n\n')

    bob_enc_keypair = DecryptingKeypair(private_key=enc)
    bob_sig_keypair = SigningKeypair(private_key=sig)

    enc_power = DecryptingPower(keypair=bob_enc_keypair)
    sig_power = SigningPower(keypair=bob_sig_keypair)
    power_ups = [enc_power, sig_power]

    doctor = Bob(
        domains={'TEMPORARY_DOMAIN'},
        is_me=True,
        federated_only=True,
        crypto_power_ups=power_ups,
        start_learning_now=True,
        abort_on_learning_error=True,
        known_nodes={ursula},
        save_metadata=False,
        network_middleware=RestMiddleware()
    )

    policy_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(policy_public_key))
    alices_sig_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(alice_signing_key))
    label = label.encode()

    doctor.join_policy(label, alices_sig_pubkey)

    message_kit = UmbralMessageKit.from_bytes(bytes.fromhex(message))

    print (message_kit == MessageKit)
    print (message_kit)
    print (MessageKit)
    print ('\n\n\n')

    data_source = Enrico.from_public_keys(
        {SigningPower: data_source},
        policy_encrypting_key=policy_pubkey
    )

    retrieved_plaintexts = doctor.retrieve(
        label=label,
        message_kit=message_kit,
        data_source=data_source,
        alice_verifying_key=alices_sig_pubkey
    )

    # the object to be sent back to front end

    # {
    #     "fileFieldCount": 2,
    #     "textFieldCount": 2,
    #     "files  (stringified)": {
    #         "fileKey1": "fileUrl1",
    #         "fileKey2": "fileUrl2"
    #     },
    #     "textFields (stringified)": {
    #         "age": "18",
    #         "name": "arvind"
    #     }
    #  }

    plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False)

    # the object from plaintext
    data_obj = createDataObject(plaintext, json_data['label'])


    return jsonify(data_obj)
Example #28
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)
Example #29
0
 def _validate(self, value):
     try:
         UmbralMessageKitClass.from_bytes(value)
     except InvalidNativeDataTypes as e:
         raise InvalidInputData(f"Could not parse {self.name}: {e}")
Example #30
0
def test_bob_retrieves_twice_via_cli(click_runner,
                                     capsule_side_channel,
                                     enacted_federated_policy,
                                     federated_ursulas,
                                     custom_filepath_2,
                                     federated_alice
                                     ):
    teacher = list(federated_ursulas)[0]

    first_message = capsule_side_channel.reset(plaintext_passthrough=True)
    three_message_kits = [capsule_side_channel(), capsule_side_channel(), capsule_side_channel()]

    bob_config_root = custom_filepath_2
    bob_configuration_file_location = os.path.join(bob_config_root, BobConfiguration.generate_filename())
    label = enacted_federated_policy.label

    # I already have a Bob.

    # Need to init so that the config file is made, even though we won't use this Bob.
    bob_init_args = ('bob', 'init',
                     '--network', TEMPORARY_DOMAIN,
                     '--config-root', bob_config_root,
                     '--federated-only')

    envvars = {'NUCYPHER_KEYRING_PASSWORD': INSECURE_DEVELOPMENT_PASSWORD}

    log.info("Init'ing a normal Bob; we'll substitute the Policy Bob in shortly.")
    bob_init_response = click_runner.invoke(nucypher_cli, bob_init_args, catch_exceptions=False, env=envvars)

    message_kit_bytes = bytes(three_message_kits[0])
    message_kit_b64_bytes = b64encode(message_kit_bytes)
    UmbralMessageKit.from_bytes(message_kit_bytes)

    retrieve_args = ('bob', 'retrieve',
                     '--mock-networking',
                     '--json-ipc',
                     '--teacher', teacher.seed_node_metadata(as_teacher_uri=True),
                     '--config-file', bob_configuration_file_location,
                     '--message-kit', message_kit_b64_bytes,
                     '--label', label,
                     '--policy-encrypting-key', bytes(federated_alice.get_policy_encrypting_key_from_label(label)).hex(),
                     '--alice-verifying-key', bytes(federated_alice.public_keys(SigningPower)).hex()
                     )

    from nucypher.cli import actions

    def substitute_bob(*args, **kwargs):
        log.info("Substituting the Policy's Bob in CLI runtime.")
        this_fuckin_guy = enacted_federated_policy.bob
        somebody_else = Ursula.from_teacher_uri(teacher_uri=kwargs['teacher_uri'],
                                                min_stake=0,
                                                federated_only=True,
                                                network_middleware=this_fuckin_guy.network_middleware)
        this_fuckin_guy.remember_node(somebody_else)
        this_fuckin_guy.controller.emitter = JSONRPCStdoutEmitter()
        return this_fuckin_guy

    _old_make_character_function = actions.make_cli_character
    try:

        log.info("Patching make_cli_character with substitute_bob")
        actions.make_cli_character = substitute_bob

        # Once...
        with GlobalLoggerSettings.pause_all_logging_while():
            retrieve_response = click_runner.invoke(nucypher_cli, retrieve_args, catch_exceptions=False, env=envvars)

        log.info(f"First retrieval response: {retrieve_response.output}")
        assert retrieve_response.exit_code == 0

        retrieve_response = json.loads(retrieve_response.output)
        for cleartext in retrieve_response['result']['cleartexts']:
            assert cleartext.encode() == capsule_side_channel.plaintexts[1]

        # and again!
        with GlobalLoggerSettings.pause_all_logging_while():
            retrieve_response = click_runner.invoke(nucypher_cli, retrieve_args, catch_exceptions=False, env=envvars)

        log.info(f"Second retrieval response: {retrieve_response.output}")
        assert retrieve_response.exit_code == 0

        retrieve_response = json.loads(retrieve_response.output)
        for cleartext in retrieve_response['result']['cleartexts']:
            assert cleartext.encode() == capsule_side_channel.plaintexts[1]
    finally:
        log.info("un-patching make_cli_character")
        actions.make_cli_character = _old_make_character_function