Exemple #1
0
    async def pack(msg: Message, wallet: WalletConnection, their_ver_key, routing_keys: list, my_ver_key=None) -> bytes:
        if not routing_keys:
            raise RuntimeError('routing_keys must not be empty')
        payload = await wallet.pack_message(
            Serializer.serialize(msg).decode(RoutingMessage.ENC),
            their_ver_key,
            my_ver_key
        )
        keys_map = {}
        for n in range(len(routing_keys)-1, 0, -1):  # example: IF routing_keys = ['k1', 'k2', 'k3'] THEN n = [2,1]
            outer_key = routing_keys[n]
            inner_key = routing_keys[n-1]
            keys_map[outer_key] = inner_key
        keys_map[routing_keys[0]] = their_ver_key

        for outer_key in routing_keys:
            inner_key = keys_map[outer_key]
            forwarded = Message({
                '@type': RoutingMessage.FORWARD,
                'to': inner_key,
                'msg': json.loads(payload.decode(RoutingMessage.ENC))
            })
            payload = await wallet.pack_message(
                Serializer.serialize(forwarded).decode(RoutingMessage.ENC),
                outer_key,
            )
        return payload
Exemple #2
0
    async def unpack_agent_message(wire_msg_bytes, wallet: WalletConnection):
        if isinstance(wire_msg_bytes, str):
            wire_msg_bytes = bytes(wire_msg_bytes, 'utf-8')
        unpacked = await wallet.unpack_message(wire_msg_bytes)
        from_key = None
        from_did = None
        their_endpoint = None
        their_routing_keys = None
        context = Context()
        if 'sender_verkey' in unpacked:
            from_key = unpacked['sender_verkey']
            from_did = await indy_sdk_utils.did_for_key(
                wallet, unpacked['sender_verkey'])
            pairwise_info = await wallet.get_pairwise(from_did)
            pairwise_meta = pairwise_info['metadata']
            their_endpoint = pairwise_meta['their_endpoint']
            their_routing_keys = pairwise_meta.get('their_routing_keys', None)
        to_key = unpacked['recipient_verkey']
        to_did = await indy_sdk_utils.did_for_key(wallet,
                                                  unpacked['recipient_verkey'])

        msg = Serializer.deserialize(unpacked['message'])

        context.their_did = from_did
        context.my_did = to_did
        context.my_ver_key = to_key
        context.their_verkey = from_key
        context.their_endpoint = their_endpoint
        context.their_routing_keys = their_routing_keys

        return msg, context
Exemple #3
0
async def test_pack_message_multi_recp_keys():
    sender = 'sender'
    recipient1 = 'recipient1'
    recipient2 = 'recipient2'
    pass_phrase = 'pass_phrase'
    await remove_wallets(sender, recipient1, recipient2)

    conn_sender = WalletConnection(sender, pass_phrase)
    conn_recipient1 = WalletConnection(recipient1, pass_phrase)
    conn_recipient2 = WalletConnection(recipient2, pass_phrase)
    await conn_sender.create()
    await conn_recipient1.create()
    await conn_recipient2.create()
    try:
        await conn_sender.open()
        await conn_recipient1.open()
        await conn_recipient2.open()

        did_recipient1, verkey_recipient1 = await conn_recipient1.create_and_store_my_did(
        )
        did_recipient2, verkey_recipient2 = await conn_recipient2.create_and_store_my_did(
        )
        message = BasicMessage.build(content='Test content')
        buf = Serializer.serialize(message).decode(),
        wired = await conn_sender.pack_message(
            buf, [verkey_recipient1, verkey_recipient2])
        unpacked1 = await conn_recipient1.unpack_message(wired)
        unpacked2 = await conn_recipient2.unpack_message(wired)
        assert unpacked1['message'] == unpacked2['message']
        assert unpacked1['recipient_verkey'] != unpacked2['recipient_verkey']
    finally:
        await conn_sender.delete()
        await conn_recipient1.delete()
        await conn_recipient2.delete()
Exemple #4
0
 async def receive_invite_link(
         cls, link: str, agent_name: str, pass_phrase: str, my_label: str, my_endpoint: str, ttl: int, my_did: str=None
 ):
     await WalletAgent.ensure_agent_is_open(agent_name, pass_phrase)
     matches = re.match("(.+)?c_i=(.+)", link)
     if not matches:
         raise BadInviteException("Invite string is improperly formatted")
     invite_msg = Serializer.deserialize(
         base64.urlsafe_b64decode(matches.group(2)).decode('utf-8')
     )
     if cls.endorsement(invite_msg):
         return await cls.receive_invite_message(invite_msg, agent_name, pass_phrase, my_label, my_endpoint, ttl)
     else:
         return None
Exemple #5
0
 async def send_message_to_endpoint_and_key(their_ver_key: str, their_endpoint: str, msg: Message,
                                            wallet: WalletConnection, my_ver_key: str=None):
     # If my_ver_key is omitted, anon-crypt is used inside pack.
     try:
         wire_message = await wallet.pack_message(
             Serializer.serialize(msg).decode('utf-8'),
             their_ver_key,
             my_ver_key
         )
     except Exception as e:
         logging.exception(str(e))
         raise
     else:
         transport = EndpointTransport(address=their_endpoint)
         await transport.send_wire_message(wire_message)
Exemple #6
0
        def build(label: str, connection_key: str, endpoint: str) -> str:
            msg = Message({
                '@type': DIDExchange.INVITE,
                'label': label,
                'recipientKeys': [connection_key],
                'serviceEndpoint': endpoint,
                # routing_keys not specified, but here is where they would be put in the invite.
            })

            b64_invite = base64.urlsafe_b64encode(
                bytes(
                    Serializer.serialize(msg).decode('utf-8'),
                    'ascii'
                )
            ).decode('ascii')
            return '{}?c_i={}'.format(endpoint, b64_invite)
Exemple #7
0
 async def send_problem_report(wallet: WalletConnection,
                               problem_code: str,
                               problem_str: str,
                               context: Context,
                               thread_id: str = None):
     err_msg = IssueCredentialProtocol.build_problem_report_for_connections(
         problem_code, problem_str, thread_id)
     try:
         wire_message = await wallet.pack_message(
             Serializer.serialize(err_msg).decode('utf-8'),
             context.their_verkey, context.my_ver_key)
     except Exception as e:
         logging.exception(str(e))
         raise
     else:
         transport = EndpointTransport(address=context.their_endpoint)
         await transport.send_wire_message(wire_message)
         return err_msg
Exemple #8
0
        def parse(invite_url: str) -> Message:
            matches = re.match('(.+)?c_i=(.+)', invite_url)
            assert matches, 'Improperly formatted invite url!'

            invite_msg = Serializer.deserialize(
                base64.urlsafe_b64decode(matches.group(2)).decode('ascii')
            )

            invite_msg.check_for_attrs(
                [
                    ('@type', DIDExchange.INVITE),
                    'label',
                    'recipientKeys',
                    'serviceEndpoint'
                ]
            )

            return invite_msg
Exemple #9
0
 async def unpack_agent_message(wire_msg_bytes, wallet: WalletConnection):
     if isinstance(wire_msg_bytes, str):
         wire_msg_bytes = bytes(wire_msg_bytes, 'utf-8')
     unpacked = await wallet.unpack_message(wire_msg_bytes)
     from_key = None
     from_did = None
     if 'sender_verkey' in unpacked:
         from_key = unpacked['sender_verkey']
         from_did = await indy_sdk_utils.did_for_key(wallet, unpacked['sender_verkey'])
     to_key = unpacked['recipient_verkey']
     to_did = await indy_sdk_utils.did_for_key(wallet, unpacked['recipient_verkey'])
     msg = Serializer.deserialize(unpacked['message'])
     msg.context = {
         'from_did': from_did,  # Could be None
         'to_did': to_did,  # Could be None
         'from_key': from_key,  # Could be None
         'to_key': to_key
     }
     return msg
Exemple #10
0
    async def unpack_agent_message(wire_msg_bytes, wallet: WalletConnection):
        print('===== 0036 unpack_agent_message ======')
        if isinstance(wire_msg_bytes, str):
            wire_msg_bytes = bytes(wire_msg_bytes, 'utf-8')
        unpacked = await wallet.unpack_message(wire_msg_bytes)
        print('unpacked: \n' + json.dumps(unpacked, indent=2, sort_keys=True))
        from_key = None
        from_did = None
        their_endpoint = None
        context = Context()
        if 'sender_verkey' in unpacked:
            from_key = unpacked['sender_verkey']
            from_did = await indy_sdk_utils.did_for_key(
                wallet, unpacked['sender_verkey'])
            pairwise_info = await wallet.get_pairwise(from_did)
            pairwise_meta = pairwise_info['metadata']
            their_endpoint = pairwise_meta['their_endpoint']
        to_key = unpacked['recipient_verkey']
        to_did = await indy_sdk_utils.did_for_key(wallet,
                                                  unpacked['recipient_verkey'])

        msg = Serializer.deserialize(unpacked['message'])

        print('from_did: ' + str(from_did))
        print('to_did: ' + str(to_did))
        print('to_key: ' + str(to_key))
        print('from_key: ' + str(from_key))
        print('their_endpoint: ' + str(their_endpoint))

        context.their_did = from_did
        context.my_did = to_did
        context.my_ver_key = to_key
        context.their_verkey = from_key
        context.their_endpoint = their_endpoint
        print('===========')
        return msg, context
Exemple #11
0
 async def __send_connection_request(self, invitation: Message):
     """Connection Request"""
     their = dict(
         label=invitation['label'],
         connection_key=invitation['recipientKeys'][0],
         endpoint=invitation['serviceEndpoint']
     )
     # Create my information for connection
     my_did, my_vk = await indy_sdk_utils.create_and_store_my_did(self.get_wallet())
     await self.get_wallet().set_did_metadata(my_did, their)
     # Send Connection Request to inviter
     request = DIDExchange.Request.build(self.label, my_did, my_vk, self.endpoint)
     try:
         wire_message = await self.get_wallet().pack_message(
             message=Serializer.serialize(request).decode('utf-8'),
             their_ver_key=their['connection_key'],
             my_ver_key=my_vk
         )
         transport = EndpointTransport(address=their['endpoint'])
         await transport.send_wire_message(wire_message)
         await self.__log('Send', request.to_dict())
     except Exception as e:
         logging.exception(str(e))
         raise
Exemple #12
0
 async def generate_invite_link(cls, label: str, endpoint: str, agent_name: str, pass_phrase: str, extra: dict=None):
     invite_msg = await cls.generate_invite_message(label, endpoint, agent_name, pass_phrase, extra)
     b64_invite = base64.urlsafe_b64encode(Serializer.serialize(invite_msg)).decode('ascii')
     return '?c_i=' + b64_invite, invite_msg
    def test_invitation_ensure_exists(self):
        conn = WalletConnection(self.WALLET_UID, self.WALLET_PASS_PHRASE)
        wallet = Wallet.objects.create(uid=self.WALLET_UID, owner=self.account)
        endpoint = Endpoint.objects.create(uid='endpoint_uid',
                                           owner=self.account,
                                           wallet=wallet,
                                           url='http://example.com/endpoint')
        # first: create wallet
        run_async(conn.create())
        run_async(conn.open())
        my_did, my_verkey = run_async(conn.create_and_store_my_did())
        run_async(conn.close())
        try:
            seed = 'blablabla-seed-'
            expected_key = '3XvPjB4EDpmBBF4sRmqVbrQXQY5vk7zjiggSCGxSkPpV'
            cred = dict(pass_phrase=self.WALLET_PASS_PHRASE, seed=seed)
            url = self.live_server_url + '/agent/admin/wallets/%s/endpoints/%s/invitations/ensure_exists/' % (
                self.WALLET_UID, endpoint.uid)
            resp = requests.post(url,
                                 json=cred,
                                 auth=HTTPBasicAuth(self.IDENTITY, self.PASS))
            self.assertEqual(200, resp.status_code)
            i1 = resp.json()

            instance = Invitation.objects.get(endpoint=endpoint)
            self.assertEqual(seed, instance.seed)
            self.assertEqual(expected_key, instance.connection_key)
            self.assertIsNone(instance.my_did)
            resp = requests.post(url,
                                 json=cred,
                                 auth=HTTPBasicAuth(self.IDENTITY, self.PASS))
            self.assertEqual(200, resp.status_code)
            i2 = resp.json()

            self.assertEqual(
                1,
                Invitation.objects.filter(connection_key=expected_key).count())

            matches = re.match("(.+)?c_i=(.+)", i1['url'])
            invite_msg1 = Serializer.deserialize(
                base64.urlsafe_b64decode(
                    matches.group(2)).decode('utf-8')).to_dict()
            del invite_msg1['@id']
            matches = re.match("(.+)?c_i=(.+)", i2['url'])
            invite_msg2 = Serializer.deserialize(
                base64.urlsafe_b64decode(
                    matches.group(2)).decode('utf-8')).to_dict()
            del invite_msg2['@id']
            self.assertDictEqual(invite_msg1, invite_msg2)

            cred['my_did'] = my_did
            resp = requests.post(url,
                                 json=cred,
                                 auth=HTTPBasicAuth(self.IDENTITY, self.PASS))
            self.assertEqual(200, resp.status_code)
            instance = Invitation.objects.get(endpoint=endpoint)
            self.assertEqual(my_did, instance.my_did)

            self.assertEqual(1, Invitation.objects.count())
            cred = dict(pass_phrase=self.WALLET_PASS_PHRASE,
                        seed=seed + 'salt')
            resp = requests.post(url,
                                 json=cred,
                                 auth=HTTPBasicAuth(self.IDENTITY, self.PASS))
            self.assertEqual(200, resp.status_code)
            self.assertEqual(2, Invitation.objects.count())
        finally:
            os.popen("pkill -f run_wallet_agent")
            sleep(1)
            run_async(conn.delete())